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

Dan*_*Dan 10 .net c# entity-framework

假设我在单个DbContext中修改来自不同DbSets的实体.

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

Bra*_*lon 16

理想情况下,您要做的只是修改您想要更改的实体,然后调用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;
}
Run Code Online (Sandbox Code Playgroud)

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

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


Rez*_*aei 5

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

但是使用此代码,您可以拒绝所有实体的更改,除了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();
Run Code Online (Sandbox Code Playgroud)

我想db是您的dbcontext的实例。