简体   繁体   中英

EF 4.3 Many to Many Relation and Junction Table Update

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}       
}

and in repository class

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();
}

i am gettng a error below like

The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.

You will need semething like this if you want to replace the existing UserActions collection in the database by the new collection you are passing into the method. Especially it is necessary that you delete the UserActions which have been removed from the collection also from the database because apparently the relationship is required and the user actions either must refer to a user entity or they must be deleted (that's what the exception says):

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();

You must translate this into your repository structure.

Thanks Slauma,Solution is

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

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

Add Users collection to Action class and Actions to User. You even can not map UserAction table if user and action in pair are unique for this table.

I answered quite the same here: Database First with Bridge Table, How to Keep It Out of Model

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM