Entity Framework级联更新

首先來看一下 示範資料庫的 ER-Model

2009-10-12_122043

User 使用者
Group 群組
UserDepartment 使用者部門

  

需求是要建立一個 User 包含 UserDepartment 以及 Group,
直接來看語法

方式一

01using (TestEntities te = new TestEntities())
02{         
03    ////新增一個 User
04    User u = new User()
05    {
06        User_name = "David",           
07        User_email = "asdtey@yahoo.com.tw",
08        ////此為多對一時的新增方式               
09        UserDepartment = te.UserDepartment.Where(a => a.UserDepartment_name == "開發部").First()
10    };
11 
12    ////新增User屬於的群組
13 
14    ////先取得要新增的群組
15    Group g1 = te.Group.Where(a => a.Group_name == "攝影社").First();
16    Group g2 = te.Group.Where(a => a.Group_name == "開發二").First();
17    ////多對多的新增方式
18    u.Group.Add(g1);
19    u.Group.Add(g2);
20 
21    te.AddToUser(u);  
22 
23    ////儲存
24    te.SaveChanges();           
25}

此方法可以順利新增一個 User 同時包含 UserDepartment 以及 Group,
不過有個問題是說仔細去看語法時,
會發現在新增之前會先去資料庫取得UserDepartment 以及 Group 的資料,才進行新增,
但我只是要新增 User ,並沒有要取得 UserDepartment 、 Group 的資料,
每次新增都先去資料庫撈資料,會影響效能,
這邊分享另一種寫法

方法二

01////方式二
02using (TestEntities te = new TestEntities())
03{
04    ////新增一個 User
05    User u = new User()
06    {
07        User_name = "David",
08        User_email = "asdtey@yahoo.com.tw",                   
09    };
10 
11    ////此為多對一時的新增方式      
12    UserDepartment userDepartment = new UserDepartment()
13    {
14        EntityKey = new EntityKey("TestEntities.UserDepartment", "UserDepartment_id", 1),
15        UserDepartment_id = 1
16    };
17    te.Attach(userDepartment); 
18    u.UserDepartment = userDepartment;
19 
20    //////多對多的新增方式
21    Group g1 = new Group()
22    {
23        EntityKey = new EntityKey("TestEntities.Group", "Group_id", 1),
24        Group_id = 1
25    };
26    te.Attach(g1);               
27    u.Group.Add(g1);
28 
29    Group g2 = new Group()
30    {
31        EntityKey = new EntityKey("TestEntities.Group", "Group_id", 2),
32        Group_id = 2
33    };
34    te.Attach(g2);
35    u.Group.Add(g2);
36 
37    ////儲存
38    te.AddToUser(u);
39    te.SaveChanges();
40}

 此方法利用EntityKey讓ObjectContext知道我們要關聯的物件是甚麼,
就不會先去資料庫撈資料,提升效能,
但是缺點是要打的code變多了,也缺少IntelliSence

再分享一下,如果只要新增User以及UserDepartment(多對一關係)時,
還可以這樣寫,

方法三

01////方式三
02using (TestEntities te = new TestEntities())
03{
04    ////新增一個 User
05    User u = new User()
06    {
07        User_name = "David",
08        User_email = "asdtey@yahoo.com.tw",
09    };
10 
11    u.UserDepartmentReference.EntityKey = new EntityKey("TestEntities.UserDepartment", "UserDepartment_id", 1);               
12 
13    ////儲存
14    te.AddToUser(u);
15    te.SaveChanges();
16}

 建議在大量新增的時候 可以使用方法二 避免影響效能及資料庫

 

一樣先來看一下 示範資料庫的 ER-Model

2009-10-12_122043

User 使用者
Group 群組
UserDepartment 使用者部門


需求是要修改 User的資料  包含 UserDepartment 以及 Group,
直接來看語法

01using (TestEntities te = new TestEntities())
02{
03    ////取得 David 資料
04    var u = te.User.Where(a => a.User_name == "David").First();
05    u.Group.Load();
06    u.UserDepartmentReference.Load();
07     
08    ////修改 Email
09    u.User_email = "asdtey@yahoo.com.tw";          
10    te.SaveChanges();
11     
12 
13    //修改使用者部門
14 
15    ////先取得要變更成的部門
16    var t = te.UserDepartment.Where(a => a.UserDepartment_name == "經理部").First();  
17    ////重新給予部門
18    u.UserDepartment = t;         
19    te.SaveChanges();
20     
21 
22    //修改群組
23 
24    ////因為 User 與 Group 為多對多的關係
25    ////因此修改方式為 刪除與新增
26 
27    ////刪除群組
28    var g = u.Group.First();           
29    u.Group.Remove(g);
30 
31    ////取得要新增的群組
32    var g1 = te.Group.Where(a => a.Group_name == "電研社").First();
33    u.Group.Add(g1);
34     
35    te.SaveChanges();
36}

 

修改部分比較簡單,下次來介紹刪除的部分

一樣先來看 ER-Model

2009-10-12_122043
 

需求是要刪除使用者(User)資料,
來看看範例

範例一

01////範例   刪除 David 的資料
02using (TestEntities te = new TestEntities())
03{           
04    ////先取得 David 的資料
05    var u = te.User.Where(a => a.User_name == "David").First();           
06 
07    ////刪除 David
08    te.DeleteObject(u);
09     
10    ////儲存變更
11    te.SaveChanges();
12}

 

這段語法看起來正常,但是一執行卻發生
 

'/ADOEntityFrameworkDemo' 應用程式中發生伺服器錯誤。

The DELETE statement conflicted with the REFERENCE constraint "FK_UserGroup_User". The conflict occurred in database "Test", table "dbo.UserGroup", column 'UserGroup_userid'.
The statement has been terminated.

描述: 在執行目前 Web 要求的過程中發生未處理的例外情形。請檢閱堆疊追蹤以取得錯誤的詳細資訊,以及在程式碼中產生的位置。
例外詳細資訊: System.Data.SqlClient.SqlException: The DELETE statement conflicted with the REFERENCE constraint "FK_UserGroup_User". The conflict occurred in database "Test", table "dbo.UserGroup", column 'UserGroup_userid'.
The statement has been terminated.

@@  原來是因為還有 Reference ,
再把語法修改一下

範例二

01////範例   刪除 David 的資料
02using (TestEntities te = new TestEntities())
03{
04    ////先取得 David 的資料
05    var u = te.User.Where(a => a.User_name == "David").First();
06                
07    ////ADO.Net Framework 在刪除的時候,會連帶一起刪除關連的資料           
08    ////但是必須先載入關連的資料
09    u.Group.Load();
10    u.UserDepartmentReference.Load();
11 
12    ////刪除 David
13    te.DeleteObject(u);
14 
15    ////儲存變更
16    te.SaveChanges();
17}

這段語法就可以順利執行囉

說明一下,ADO.Net Entity Framework 在處理關聯式資料的時候,會把相關的所有資料一起刪除,
但是前提是在刪除前,必須先使用【Load】方法,把相關聯資料載入

 

posted @ 2010-06-29 13:55  hq5460  阅读(1137)  评论(0编辑  收藏  举报