简体   繁体   English

实体框架在新的DBContext中更新多对多关系

[英]Entity Framework update many-to-many relation in new DBContext

I have a many-to-many relation between groups and users. 组与用户之间存在多对多关系。 I would like to load elements from a DBContext, modify them, and then attach them to a new DBContext (for various reason it is not a good solution to keep the context alive between loading and saving). 我想从DBContext加载元素,进行修改,然后将它们附加到新的DBContext(由于各种原因,在加载和保存之间保持上下文不活跃不是一个好的解决方案)。

In the code below I have recreated the scenario, but for some reason reattaching and saving doesn't seem to work. 在下面的代码中,我重新创建了该场景,但是由于某种原因,重新附加和保存似乎不起作用。

public class TUser
{
    [Key]
    public int Id { get; set; }

    public ICollection<TGroup> Groups { get; set; } = new List<TGroup>();
}

public class TGroup
{
    [Key]
    public int Id { get; set; }
}

public class UserGroupDbContext : DbContext
{
    public UserGroupDbContext(DbConnection existingConnection, bool contextOwnsConnection)
        : base(existingConnection, contextOwnsConnection)
    {
    }

    public DbSet<TUser> Users { get; set; }
    public DbSet<TGroup> Groups { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<TUser>()
            .HasMany(u => u.Groups)
            .WithMany()
            .Map(m =>
            {
                m.MapLeftKey("UserId");
                m.MapRightKey("GroupId");
                m.ToTable("UserGroup");
            });

        base.OnModelCreating(modelBuilder);
    }
}

public class UserRepositoryTest
{
    public UserRepositoryTest()
    {
        var group1 = new TGroup();
        var group2 = new TGroup();
        var group3 = new TGroup();
        var user = new TUser { Groups = new List<TGroup> { group1, group2 } };

        var dbContextFixture = new DbContextFixture<UserGroupDbContext>();
        using (var dbContext = dbContextFixture.CreateContext())
        {
            dbContext.Groups.Add(group1);
            dbContext.Groups.Add(group2);
            dbContext.Groups.Add(group3);
            dbContext.Users.Add(user);

            dbContext.SaveChanges();
        }

        user.Groups.Remove(group2);
        user.Groups.Add(group3);

        using (var dbContext = dbContextFixture.CreateContext())
        {
            dbContext.Users.Attach(user);

            dbContext.SaveChanges();
        }

        using (var dbContext = dbContextFixture.CreateContext())
        {
            var loadedUser = dbContext.Users.Include(u => u.Groups).Single();
            Assert.True(loadedUser.Groups.Any(g => g.Id == group1.Id));
            Assert.True(loadedUser.Groups.Any(g => g.Id == group3.Id)); // <-- This line fails
            Assert.False(loadedUser.Groups.Any(g => g.Id == group2.Id)); // <-- This line fails
        }
    }
}

When you have one already loaded entity and from another DBContext and want to change it with another DBContext than you need to attach you Model into your new DBContext. 如果您已经从另一个DBContext中加载了一个实体,并且想用另一个DBContext进行更改,则无需将模型附加到新的DBContext中。

This happens since you new DbConext can not know if something changes since it can not keep track of it. 发生这种情况是因为您新的DbConext无法跟踪某些变化,因此无法知道它是否发生了变化。

Se the link below. Se下面的链接。

https://docs.microsoft.com/en-us/ef/ef6/saving/change-tracking/entity-state https://docs.microsoft.com/en-us/ef/ef6/saving/change-tracking/entity-state

Hope this helps 希望这可以帮助

When you modify your entity before Attaching to Context, the Context will not be aware of modification. 当您在附加到上下文之前修改实体时,上下文将不知道修改。 You should either modify entity after attaching or set it's State to Modified 您应该在附加后修改实体,或者将其状态设置为“已修改”

Attaching an existing but modified entity to the context 将现有但已修改的实体附加到上下文

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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