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

时间:2018-09-06 08:59:50

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

我在群组和用户之间存在多对多关系。我想从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
        }
    }
}

2 个答案:

答案 0 :(得分:1)

当您已经从另一个DBContext中加载了一个实体,并且想要用另一个DBContext对其进行更改时,不需要将模型附加到新的DBContext中。

发生这种情况是因为您新的DbConext无法跟踪某些内容,因为它无法跟踪它。

请点击下面的链接。

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

希望这会有所帮助

答案 1 :(得分:1)

当您在附加到上下文之前修改实体时,上下文将不知道修改。您应该在附加实体后修改实体,或者将其状态设置为已修改

Attaching an existing but modified entity to the context