首页 > 解决方案 > 实体框架更新新 DBContext 中的多对多关系

问题描述

我在组和用户之间有多对多的关系。我想从 DBContext 加载元素,修改它们,然后将它们附加到新的 DBContext (由于各种原因,在加载和保存之间保持上下文活跃不是一个好的解决方案)。

在下面的代码中,我重新创建了场景,但由于某种原因,重新附加和保存似乎不起作用。

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

标签: c#entity-frameworkmany-to-many

解决方案


当您已经从另一个 DBContext 加载了一个实体并希望使用另一个 DBContext 更改它时,您需要将模型附加到新的 DBContext 中。

发生这种情况是因为您新的 DbConext 无法知道是否有更改,因为它无法跟踪它。

请参阅下面的链接。

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

希望这可以帮助


推荐阅读