简体   繁体   中英

Many to one relation with attached entity

I have a many to many relation that I want to update using a detached entity that I have attached to the context (deserilized from WebApi).

I have created this helper method that works for Many to one relations

public void SetEntityState<TEntity>(IEnumerable<TEntity> source) where TEntity : EntityBase, IDeletable
{
    foreach (var deletable in source.ToList())
    {
        var entry = Entry(deletable);
        if (deletable.Deleted)
            entry.State = EntityState.Deleted;
        else
            entry.State = deletable.Id == 0 ? EntityState.Added : EntityState.Modified;
    }
}  

Used like

db.Entry(user).State = EntityState.Modified; 

db.SetEntityState(user.HomeFolders); //Works because HomeFolders is a many to one relation    
db.SetEntityState(user.Roles) //Does not work because Roles is a many to many relation

This does not ofcourse work with a Many to many relation because entry.State = EntityState.Deleted will point to the referenced enity and try to delete that instead of the row in the relation table.

So how can I delete/add many to many relations on a newly attached entity?

edit: Config

public class UserConfiguration : EntityTypeConfiguration<User>
{
    public UserConfiguration()
    {
        HasKey(u => u.Id);

        Property(u => u.Username)
            .IsRequired()
            .HasMaxLength(50);

        Property(u => u.Password)
            .IsRequired()
            .HasMaxLength(128);

        HasMany(s => s.HomeFolders)
            .WithRequired()
            .Map(
                m => m.MapKey("UserId")
            );

        HasMany(p => p.Roles)
            .WithMany()
            .Map(m =>
            {
                m.ToTable("UserRole");
                m.MapLeftKey("UserId");
                m.MapRightKey("RoleId");
            });

        ToTable("User");
    }
}

Models

public abstract class EntityBase
{
    public int Id { get; set; }
}

public class Role : EntityBase,  IDeletable
{
    public string Name { get; set; }
    public bool Deleted { get; set; }
}

public class User : EntityBase
{
    public string Username { get; set; }
    public string Password { get; set; }

    public virtual ICollection<HomeFolder> HomeFolders { get; set; }
    public virtual ICollection<Role> Roles { get; set; }
}

update: Delete actually works if I remove the Role after the user is attached. But new roles that is in teh list will not be added

Update code as of latest revision, Add role still not working

public void UpdateUser(User user)
{

    db.Entry(user).State = EntityState.Modified;

    db.SetEntityState(user.HomeFolders);
    user.Roles.Where(r => r.Deleted).ToList().ForEach(r => user.Roles.Remove(r));

    if (string.IsNullOrEmpty(user.Password))
        db.Entry(user).Property(x => x.Password).IsModified = false;
    else
    {
        SetPassword(user);
    }

    db.SaveChanges();
}

Why do you chose the hard path and deal with EntityState ?

Simply remove the roles, if user is attached:

user.roles.ToList().ForEach(r=> user.Roles.Remove(r))

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