实体框架查询刚刚添加但未保存的值

Posted

技术标签:

【中文标题】实体框架查询刚刚添加但未保存的值【英文标题】:Entity framework query on just added but not saved values 【发布时间】:2016-12-06 15:47:14 【问题描述】:

我使用 Entity Framework 已有几年了,现在我遇到了一个小问题。

我将一个实体添加到我的表中,

Entities.dbContext.MyTable.Add(obj1);

这里没问题。

然后,我想在 MyTable 上做一个查询,比如

Entities.dbContext.MyTable.Where(.....)

上面的代码会在数据库中查询我的MyTable。

有没有办法在 saveChanges 之前查询刚刚添加的值? (obj1) 怎么样?

更新

我为什么需要这个?因为,对于我添加的每个新元素,我都需要编辑上一条和下一条记录中的一些值(此表中有一个日期时间字段)

更新2

假设我必须添加很多对象,但我仅在添加最后一项后才调用 saveChanges。每次添加新项目时,我都会读取它的日期时间字段,并在数据库中搜索上一条和下一条记录。在这里,我编辑了上一条记录和下一条记录的字段。现在,问题来了:如果我插入另一个项目,例如,下一个项目是“Obj1”,我必须找到并编辑它,但我找不到它,因为我没有保存我的更改。现在清楚了吗?

【问题讨论】:

您为什么要这样做?您已经拥有该对象,它存储为obj1 只要您调用 SaveChanges,obj1 就会包含刚刚保存的任何内容,例如它的主键 - 无需重新获取它。 @AlfieGoodacre 我编辑了这个问题来回答你:) @PieroAlberto 我还是很困惑,你有这个对象,所以你仍然可以用它来编辑其他值 @Darren 如果数据库上有用于创建日期或其他计算的触发器,则必须重新加载对象才能获取这些值。 【参考方案1】:

您应该能够通过更改跟踪器将添加的实体从 dbContext 中取出,如下所示:

 var addedEntities = dbContext.ChangeTracker.Entries()
   .Where(x => x.State == EntityState.Added && x.Entity is Mytable)
   .Select(x => x.Entity as MyTable)
   .Where(t => --criteria--);

或者使用type testing with pattern matching in c# 7.0:

var addedEntities = dbContext.ChangeTracker.Entries()
   .Where(x => x.State == EntityState.Added && x.Entity is Mytable t && --test t for criteria--)
   .Select(x => x.Entity as MyTable);

因为您只查询添加的实体,您可以将其与

dbContext.MyTable.Where(t => --criteria--).ToList().AddRange(addedEntities);

获取所有相关对象

【讨论】:

这是一个很好的解决方案。但是,它对我不起作用。在我的例子中,Entity.GetType().Name 附加了一个 GUID。所以我也考虑BaseType。 Where(x => x.State == EntityState.Added && (x.Entity.GetType() == typeof(MyTable) || x.Entity.GetType().BaseType == typeof(MyTable))) 你能在这里提示一下“addEntities”吗? ***.com/questions/41982691/… 有什么方法可以在不使用 ChangeTracker 的情况下完成此任务? @onhax 我认为没有简单的方法。我相信ChangeTracker 是 EF 内部使用的 DbSet<T>Local 属性在***.com/a/8468456/548020 中描述可能是更方便的替代方案【参考方案2】:

我认为这对 Transactions 来说是一个很好的情况。我假设您使用的是 EF 6,因为您没有提供版本。 =)

UPDATE2 更改

public void BulkInsertObj(List<TEntity> objList)

    using (var context = new dbContext()) 
     
        using (var dbContextTransaction = context.Database.BeginTransaction()) 
          
            try 
             
                foreach(var obj1 in objList)
                
                    dbContext.MyTable.Add(obj1);

                    //obj1 should be on the context now 
                    var previousEntity = dbContext.MyTable.Where(.....) //However you determine this
                    previousEntity.field = something

                    var nextEntity = dbContext.MyTable.Where(.....) //However you determine this
                    nextEntity.field = somethingElse
                

                context.SaveChanges(); 
                dbContextTransaction.Commit(); 
             
            catch (Exception) 
             
                dbContextTransaction.Rollback(); 
             
         
     

MSDN EF6 Transactions

【讨论】:

以上是关于实体框架查询刚刚添加但未保存的值的主要内容,如果未能解决你的问题,请参考以下文章

创建了核心数据实体但未保存属性

保存已编辑的核心数据实体未保存

实体框架 ChangeTracker 流并保存到查询

实体框架,查询包含上下文更改的dbset,而不调用保存更改

当我从未将实体添加到上下文时,实体框架错误地保存了它

用户输入的值保存到 Core Data (?) 但未出现在表视图中