2015-09-25 123 views
4

在实体框架(6.1.3)的DbSet实体集合中,添加新项目时,以后不会从集合返回。这是奇怪的和意外的。以下是一些收集的示例代码:DbSet:缺少添加项目

dbContext.Entities.ToArray(); 
// contains 3 entries 
dbContext.Entities.Add(new Entity()); 
dbContext.Entities.ToArray(); 
// still contains 3 entries 

这是怎么回事?当我在Visual Studio的直接窗口中查询dbContext.Entities时,它会说“Local:Count = 4”。为什么它会隐藏我的新项目?

更新:如果这个集合没有做明显的事情 - 返回之前添加的东西 - 我需要做些什么呢?它首先被调用时必须返回数据库中的所有记录,并且必须在稍后调用时包含所有更改(添加和删除)。 SaveChanges仅在用户编辑完成后调用。之前需要收集!当用户完成编辑时,SaveChanges也可能在某个地方被调用,但代码可能会返回并在稍后再次显示该视图。

+0

你尝试'context.Entities.Find(ID)'? – Andrei

+0

'Entities'只是一个查询,'ToArray()'将通过从数据库中提取来实现查询(并且可能***合并一些本地缓存的结果)。在这种情况下,您的新实体不会在本地缓存以及保存到数据库,因此完全没有结果。 – Hopeless

+0

“Local:Count = 4”输出并不表示它已被缓存?当我添加东西,而他们没有被缓存,那么他们将如何得到保存呢?保存工作正常,但我只能在程序重启后到达那里。我需要立即购买新产品。 – ygoe

回答

4

A DbSet有一个属性Local。这是包含所有元素的ObservableCollectionDbSet对象本身仅表示对数据库的查询。

Local属性的文档:

获取表示在这个组中的所有 增加,持平和修改实体的局部视图一个ObservableCollection。随着实体从上下文添加或删除,此本地视图 将保持同步。 同样,添加到本地视图或从本地视图中删除的实体将自动添加到上下文或从上下文中删除。

所以,如果你想访问的元素,总是使用Local属性来做到这一点。

+0

我已经将我的代码更改为将所有记录加载到本地集合中,然后从中获取所有相关项目。我不应该忘记写额外的'.Local',否则会导致意外的行为。 'Add'和'Remove'直接使用'DbSet'。 – ygoe

0

您必须保存更改。尝试

dbContext.State = EntityState.Added; 
dbContext.SaveChanges(); 
+0

我不想在编辑过程中保存更改。 – ygoe

+0

那么,直到您保存更改后,数据库才会更改。 dbContext.Entities.Add(新实体())只是暂存更改。 – dylanthelion

+0

并且要清楚:dbContext.Entities.ToArray()确实查询数据库,就像(我认为)所有其他不改变数据库的方法一样。 .Add(),.Delete和(我认为)所有其他会改变数据库的方法都不会。 – dylanthelion

2

添加新的实体后,必须保存使用的DbContext对象的变化,使用 dbContext.SaveChanges();或dbContext.EntityState.Added

+0

查看其他答案。我现在无法保存更改。我还没有完成编辑。我怎样才能得到所有未保存的物品加上保存的物品呢? – ygoe

0

你可以用下面的代码获取的所有项目,

foreach (var track in dbContext.ChangeTracker.Entries()) 
{ 
    if (track.State == EntityState.Deleted) 
     Entity s = (Entity)track.OriginalValues.ToObject(); 
    else 
     Entity s = (Entity)track.CurrentValues.ToObject(); 
}