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();
}
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
@frabiacca: Xem Chỉnh sửa của tôi. – Slauma
Tôi đã thử .. và nó hoạt động !! :) thx rất nhiều slauma – frabiacca