简体   繁体   English

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

[英]How can I tell Entity Framework to save changes only for a specific DbSet?

Let's say I modify entities from different DbSets within a single DbContext. 假设我在单个DbContext中修改来自不同DbSets的实体。

How can I tell Entity Framework, when calling SaveChanges(), to save changes only for a specific DbSet? 在调用SaveChanges()时,如何保存Entity Framework以仅保存特定DbSet的更改?

Ideally, what you would do is just modify the entities you want to change, then call SaveChanges() then modify the other entities. 理想情况下,您要做的只是修改要更改的实体,然后调用SaveChanges()然后修改其他实体。 However, if that is not possible I would add an overload of SaveChanges() that looks like this. 但是,如果这是不可能的,我会添加一个看起来像这样的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;
}

Initially you find all entities whose state is not unchanged and save their entry. 最初,您会找到状态未更改的所有实体并保存其条目。 Then you set the state of every entity that isn't of your type TEntity and set their state to unchanged. 然后设置不属于您的TEntity类型的每个实体的状态,并将其状态设置为不变。 Then call the base.SaveChanges() to save all changes to entities of your type. 然后调用base.SaveChanges()以保存对您的类型实体的所有更改。

Then, by looping through the saved entries, you can reset their original states back to them. 然后,通过循环保存的条目,您可以将其原始状态重置为它们。 This way you catch all adds/updates/deletes that aren't of your type, and restore them so that the next call to SaveChanges() doesn't lose their changes. 这样,您将捕获所有不属于您的类型的添加/更新/删除,并将其还原,以便下次调用SaveChanges()不会丢失其更改。

Before using the below code, you should know if you want to save only a specific set of entities, then it means you should use different instance of your db context for that unit of your work. 在使用下面的代码之前,您应该知道是否只想保存一组特定的实体,这意味着您应该为您的工作单元使用不同的db上下文实例。

But using this code you can reject changes of all entities except YourSpecialEntity : 但是使用此代码可以拒绝除YourSpecialEntity之外的所有实体的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();

I suppose db is an instance of your dbcontext. 我想db是dbcontext的一个实例。

I am new to EF and I had the same problem. 我是EF的新手,我遇到了同样的问题。 In my storage program i eg sumit only articleId and OwnerId for a new stock because i see no need for hidden fields in my mvc-form. 在我的存储程序中,例如,只将sumId和OwnerId汇总为一个新股票,因为我认为我的mvc表格中不需要隐藏字段。 At first EF created new entries in article and customer database, but i only wanted to insert a new item in the stocks table. 起初EF在文章和客户数据库中创建了新条目,但我只想在库存表中插入一个新项目。 So the solution is quite simple: For all entities you know you don´t want to save them type this: 因此解决方案非常简单:对于您知道不想保存的所有实体,请键入以下内容:

           //prevent Owner to be saved (again)
            db.Entry(stockItem.Owner).State = EntityState.Unchanged;

          //prevent article to be saved (again)  
           db.Entry(stockItem.ArticleItem).State = EntityState.Unchanged;

            db.Stocks.Add(stockItem);

           //now just the properties (-> dbset of the stockItem get´s saved)
            await db.SaveChangesAsync();
            return RedirectToAction("Index");

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

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