2012-01-15 31 views
17

Tôi đã sử dụng EF4 (không phải mã đầu tiên) kể từ một năm, vì vậy tôi không thực sự là một chuyên gia với nó. Tôi nghi ngờ việc sử dụng mối quan hệ nhiều-nhiều liên quan đến việc lưu cập nhật n.khung thực thể cập nhật nhiều mối quan hệ: ảo hoặc không

Tôi đọc ở đâu đó trên stackoverflow (tôi không thể tìm thấy url nữa) mà một giải pháp - để cập nhật mối quan hệ nhiều-nhiều hiện có - là không khai báo thuộc tính "ảo"; nhưng, nếu tôi làm theo cách này, động cơ không thể tải dữ liệu với tải dễ dàng.

Bạn có thể giải thích cho tôi lý do không? Otherwire, bạn có thể vui lòng giúp tôi trong việc tìm kiếm một số tài liệu tuyệt vời về chủ đề này?

thx

Trả lời

56

Bạn có thể cập nhật một cách này nhiều-nhiều mối quan hệ (như là một ví dụ trong đó cung cấp cho người dùng 3 vai trò 5):

using (var context = new MyObjectContext()) 
{ 
    var user = context.Users.Single(u => u.UserId == 3); 
    var role = context.Roles.Single(r => r.RoleId == 5); 

    user.Roles.Add(role); 

    context.SaveChanges(); 
} 

Nếu bộ sưu tập User.Roles được khai báo là virtual sự dòng user.Roles.Add(role); thực sự sẽ kích hoạt tải chậm có nghĩa là tất cả các vai trò cho người dùng được tải trước từ cơ sở dữ liệu trước khi bạn thêm vai trò mới.

Điều này thực tế đáng lo ngại vì bạn không cần tải toàn bộ bộ sưu tập Roles để thêm vai trò mới cho người dùng.

Nhưng điều này không có nghĩa là bạn phải xóa từ khóa virtual và bỏ hoàn toàn việc tải chậm. Bạn chỉ có thể tắt tải lười biếng trong tình huống cụ thể này:

using (var context = new MyObjectContext()) 
{ 
    context.ContextOptions.LazyLoadingEnabled = false; 

    var user = context.Users.Single(u => u.UserId == 3); 
    var role = context.Roles.Single(r => r.RoleId == 5); 

    user.Roles = new List<Role>(); // necessary, if you are using POCOs 
    user.Roles.Add(role); 

    context.SaveChanges(); 
} 

Sửa

Nếu bạn muốn cập nhật toàn bộ vai trò bộ sưu tập của một người sử dụng tôi muốn để tải về vai trò ban đầu với tải háo hức (= Include). Bạn cần danh sách này anyway để có thể loại bỏ một số vai trò, do đó bạn không cần phải chờ đợi cho đến khi bốc lười biếng đọc chúng từ cơ sở dữ liệu:

var newRolsIds = new List<int> { 1, 2, 5 }; 
using (var context = new MyObjectContext()) 
{ 
    var user = context.Users.Include("Roles") 
     .Single(u => u.UserId == 3); 
    // loads user with roles, for example role 3 and 5 

    var newRoles = context.Roles 
     .Where(r => newRolsIds.Contains(r.RoleId)) 
     .ToList(); 

    user.Roles.Clear(); 
    foreach (var newRole in newRoles) 
     user.Roles.Add(newRole); 

    context.SaveChanges(); 
} 

Thay vì tải các vai trò mới từ cơ sở dữ liệu bạn cũng có thể đính kèm chúng từ bạn biết trong ví dụ giá trị thuộc tính khóa. Bạn cũng có thể xóa chính xác vai trò bị thiếu thay vì xóa toàn bộ bộ sưu tập và thay vì thêm lại vai trò hiện tại:

var newRolsIds = new List<int> { 1, 2, 5 }; 
using (var context = new MyObjectContext()) 
{ 
    var user = context.Users.Include("Roles") 
     .Single(u => u.UserId == 3); 
    // loads user with roles, for example role 3 and 5 

    foreach (var role in user.Roles.ToList()) 
    { 
     // Remove the roles which are not in the list of new roles 
     if (!newRoleIds.Contains(role.RoleId)) 
      user.Roles.Remove(role); 
     // Removes role 3 in the example 
    } 

    foreach (var newRoleId in newRoleIds) 
    { 
     // Add the roles which are not in the list of user's roles 
     if (!user.Roles.Any(r => r.RoleId == newRoleId)) 
     { 
      var newRole = new Role { RoleId = newRoleId }; 
      context.Roles.Attach(newRole); 
      user.Roles.Add(newRole); 
     } 
     // Adds roles 1 and 2 in the example 
    } 
    // The roles which the user was already in (role 5 in the example) 
    // have neither been removed nor added. 

    context.SaveChanges(); 
} 
+0

thx Slauma. Tôi hiểu trường hợp tôi muốn thêm một Role mới vào collection.Roles. Những gì tôi không thể hiểu là trường hợp chung mà tôi phải thao tác một tập hợp các Vai trò. Ví dụ: user.Roles chứa 3,5 vai trò; sau đó, tôi chọn để cập nhật user.Roles để nó chứa 1,2,5 (tôi phải loại bỏ 3 và tôi phải thêm 1,2 trong user.Roles). Nó có hoạt động giống nhau không? – frabiacca

+1

@frabiacca: Xem Chỉnh sửa của tôi. – Slauma

+1

Tôi đã thử .. và nó hoạt động !! :) thx rất nhiều slauma – frabiacca

Các vấn đề liên quan