EF 4.3多对多关系和连接表更新

时间:2012-03-23 13:43:50

标签: c# .net entity-framework entity-framework-4.3

public class User
{
    public int Id{ get; set; }
    public ICollection<UserAction> UserActions{ get; set; }
    public string Name{ get; set; }
}

public class Action
{
    public int Id{ get; set; }
    public string Name{ get; set; }
    public ICollection<UserAction> UserActions{ get; set; }
}

public UserAction
{
    public int Id{ get; set; }
    public User User{ get; set; }
    public Action Action{ get; set; }
    public int Type {get;set}       
}

并在存储库类

public void Update(User user,List<UserAction> actions)
{
    User entity = this.GetUser(user.Id);           
    entity.UserActions.Clear();
    entity.UserActions= actions;
    this.siteRepository.Update<SiteUser>(user);
    this.siteRepository.UnitOfWork.SaveChanges();
}

我得到的错误如下

操作失败:无法更改关系,因为一个或多个外键属性不可为空。当对关系进行更改时,相关的外键属性将设置为空值。如果外键不支持空值,则必须定义新关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象。

3 个答案:

答案 0 :(得分:2)

如果要通过传递给方法的新集合替换数据库中的现有UserActions集合,则需要这样的事情。特别是有必要从数据库中删除已从集合中删除的UserActions,因为显然需要关系,用户操作必须引用用户实体或必须删除它们(这就是异常说):

User entity = context.Users.Include(u => u.UserActions)
    .Single(u => u.Id == user.Id);

context.Entry(entity).CurrentValues.SetValues(user);
foreach (var userAction in entity.UserActions.ToList())
    if (!user.UserActions.Any(ua => ua.Id == userAction.Id))
        context.UserActions.Remove(userAction);   // DELETE is important here!

foreach (var userAction in user.UserActions)
{
    var userActioninDB = entity.UserActions
        .SingleOrDefault(ua => ua.Id == userAction.Id);
    if (userActionInDB == null)
        entity.UserActions.Add(userActioninDB);
    else
        context.Entry(userActioninDB).CurrentValues.SetValues(userAction);
}

context.SaveChanges();

您必须将其转换为您的存储库结构。

答案 1 :(得分:1)

感谢Slauma,解决方案是

List<UserAction> actions = new List<UserAction>(user.UserActions.ToList());

foreach (var action in actions )
{
  Delete<UserAction>(action);
}

答案 2 :(得分:0)

将User集合添加到Action类和Actions to User。如果用户和对中的操作对于此表是唯一的,则甚至无法映射UserAction表。

我在这里的回答非常相似: Database First with Bridge Table, How to Keep It Out of Model