如何告诉Entity Framework仅保存特定DbSet的更改?

时间:2015-10-29 00:14:18

标签: c# .net entity-framework

假设我在单个DbContext中修改了不同DbSets中的实体。

如何在调用SaveChanges()时告诉Entity Framework仅保存特定DbSet的更改?

3 个答案:

答案 0 :(得分:15)

理想情况下,您要做的只是修改要更改的实体,然后调用SaveChanges()然后修改其他实体。但是,如果不可能,我会添加SaveChanges()的重载,看起来像这样。

public int SaveChanges<TEntity>() where TEntity : class
{
    var original = this.ChangeTracker.Entries()
                .Where(x => !typeof(TEntity).IsAssignableFrom(x.Entity.GetType()) && x.State != EntityState.Unchanged)
                .GroupBy(x => x.State)
                .ToList();

    foreach(var entry in this.ChangeTracker.Entries().Where(x => !typeof(TEntity).IsAssignableFrom(x.Entity.GetType())))
    {
        entry.State = EntityState.Unchanged;
    }

    var rows = base.SaveChanges();

    foreach(var state in original)
    {
        foreach(var entry in state)
        {
            entry.State = state.Key;
        }
    }

    return rows;
}

最初,您会找到状态未更改的所有实体并保存其条目。然后设置不属于您的类型TEntity的每个实体的状态,并将其状态设置为未更改。然后调用base.SaveChanges()将所有更改保存到您的类型实体。

然后,通过循环保存的条目,您可以将其原始状态重置为它们。通过这种方式,您可以捕获不属于您的类型的所有添加/更新/删除,并将其还原,以便下次调用SaveChanges()时不会丢失其更改。

答案 1 :(得分:5)

在使用下面的代码之前,您应该知道是否只想保存一组特定的实体,这意味着您应该为您的工作单元使用不同的db上下文实例。

但是使用此代码,您可以拒绝除YourSpecialEntity以外的所有实体的更改:

db.ChangeTracker.Entries()
                .Where(x => x.State == EntityState.Modified &&
                            !typeof(YourSpecialEntity).IsAssignableFrom(x.Entity.GetType()))
                .ToList()
                .ForEach(entry => {
                    entry.CurrentValues.SetValues(entry.OriginalValues);
                });

db.SaveChanges();

我认为db是dbcontext的一个实例。

答案 2 :(得分:0)

我是EF的新手,并且遇到了同样的问题。在我的存储程序中,例如,我只为新股票求购了articleId和OwnerId,因为我认为我的mvc表单中不需要隐藏字段。最初,EF在商品和客户数据库中创建了新条目,但我只想在stocks表中插入一个新项目。 因此,解决方案非常简单: 对于您知道不想保存的所有实体,请键入以下内容:

Application Gateway