首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

ADO.NET Entity Framework 深度解析(五):實體新增、修改、刪除與關聯操作全攻略

     編輯:關於.NET

Entity Framework 透過 ObjectContext 管理實體生命週期,開發者只需操作實體物件屬性與集合,呼叫 SaveChanges() 即可自動生成對應的 INSERT、UPDATE、DELETE T-SQL 指令。本文系統整理 CRUD 核心操作、關聯實體同步新增、以及刪除時的外鍵約束處理。

修改現有實體

using (var context = new NorthwindEntities())
{
    // 1. 擷取實體(LINQ to Entities 建議用 First(),SingleOrDefault() 不支援)
    var emp = context.Employees.First(e => e.EmployeeID == 1);

    if (emp != null)
    {
        // 2. 修改屬性
        emp.City = "San Francisco";
        emp.Notes = "New notes for employee 1";

        // 3. 儲存變更,回傳受影響實體數
        int affected = context.SaveChanges();
        Console.WriteLine("異動筆數:" + affected);
    }
}

新增單一實體

EF 為每個實體型別自動產生 AddTo<EntitySetName> 方法,亦可使用通用 AddObject:

var newEmp = new Employee
{
    FirstName = "Jan",
    LastName = "Jansen"
    // EmployeeID 為 Identity 欄位,由資料庫自動產生,此處無需指定
};

context.AddToEmployees(newEmp); // 或 context.AddObject("Employees", newEmp);
context.SaveChanges();

進階:使用靜態工廠方法建立實體(所有非 Nullable 屬性必須在建構時指定):

// Employee.CreateEmployee(EmployeeID, LastName, FirstName, ...)
var emp = Employee.CreateEmployee(0, "Jansen", "Jan"); // ID 傳 0 佔位
context.AddToEmployees(emp);
context.SaveChanges();

新增實體與其關聯子實體(一對多)

透過導覽屬性集合 .Add() 建立關聯,EF 會依順序生成多條 INSERT 並自動回填外鍵:

var newCat = new Category
{
    CategoryName = "Software",
    Description = "Software products"
};

// 建立關聯產品
newCat.Products.Add(new Product { ProductName = "Microsoft Visual Studio 2008" });
newCat.Products.Add(new Product { ProductName = "Microsoft Office 2007" });

context.AddToCategories(newCat);
context.SaveChanges();

生成的 T-SQL 批次(簡化):

-- 1. 插入 Category,取回 SCOPE_IDENTITY() 作為 CategoryID
INSERT [dbo].[Categories]([CategoryName], [Description], [Picture])
VALUES (@0, @1, NULL); SELECT [CategoryID] FROM [dbo].[Categories] WHERE @@ROWCOUNT > 0 AND [CategoryID] = scope_identity()

-- 2. 插入 Product 1,自動帶入上一步取得的 CategoryID
INSERT [dbo].[Products]([ProductName], [CategoryID], ...) VALUES (@0, @1, ...)

-- 3. 插入 Product 2,同樣帶入 CategoryID
INSERT [dbo].[Products]([ProductName], [CategoryID], ...) VALUES (@0, @1, ...)

刪除實體與外鍵約束處理

var cat = context.Categories.First(c => c.CategoryName == "Software");
context.DeleteObject(cat); // 或 context.DeleteObject(entityKey)
context.SaveChanges();

常見錯誤: 若資料庫外鍵 FK_Products_Categories 未設定 Cascade Delete,刪除擁有子產品的分類會拋出例外:

"The DELETE statement conflicted with the REFERENCE constraint \"FK_Products_Categories\". The conflict occurred in database \"Northwind\", table \"dbo.Products\", column \"CategoryID\"."

解決方案:在 SSMS 設定外鍵 Cascade Delete

設定外鍵刪除規則為 Cascade

或在程式碼中先手動刪除子實體:

var cat = context.Categories.Include("Products").First(c => c.CategoryName == "Software");
// 先刪除所有關聯產品
foreach (var p in cat.Products.ToList())
    context.DeleteObject(p);

context.DeleteObject(cat);
context.SaveChanges();

核心方法對照表

操作ObjectContext 方法LINQ to SQL 對應
新增AddTo<EntitySet>(entity) / AddObject(setName, entity)Table.InsertOnSubmit(entity)
修改直接修改屬性,SaveChanges()直接修改屬性,SubmitChanges()
刪除DeleteObject(entity) / DeleteObject(entityKey)Table.DeleteOnSubmit(entity)
儲存SaveChanges() 回傳異動實體數SubmitChanges()

關鍵提醒

  • SaveChanges() 以交易方式執行,全部成功或全部回滾。
  • Identity/Computed 欄位在 SaveChanges() 後會自動回填至實體屬性。
  • 關聯端(Navigation Property)修改同樣會被追蹤,無需額外呼叫方法。
  • 大量資料操作時,考慮分批 SaveChanges() 或使用 SqlBulkCopy 繞過 EF 以提升效能。

掌握這些核心操作模式,即能駕輕就熟地以物件導向方式操作關聯式資料,享受 EF 帶來的開發效率與維護性優勢。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved