我正在使用C#,.NET(4.0)和Entity Framework连接到SQL CE 4.0。
我查询了一些具有特定属性的对象,但只有当数据已经保存到数据库时,查询才返回满足搜索条件的对象,这不是问题,更大的问题是如果数据已更改但尚未保存到数据库它仍然符合搜索条件。
示例:
var query = from location in mainDBContext.Locations
where location.InUse == true
select location;
此查询还返回其中location.InUse = false的对象,如果InUse在从DB加载时为真,然后在代码中稍后更改。
这是来自其中一个查询结果对象的屏幕截图。
我真的不明白为什么会这样做。我会理解,如果这个查询总是查询数据库,我会得到这个对象的旧版本(因此InUse会是真的)。
感谢您的时间和答案。
答案 0 :(得分:3)
这就是EF内部运作的方式。
每个由其键唯一标识的实体只能由上下文跟踪一次 - that is called identity map。因此,执行查询的次数并不重要。如果查询返回跟踪的实体,并且如果它在同一个上下文实例上重复执行,则它将始终返回相同的实例。
如果在应用程序中修改了实例但未保存到数据库,则将在数据库上执行查询,其中将评估持久状态,但实现过程将默认使用应用程序中的当前数据而不是从数据库中检索的数据。数据库。您可以强制查询从数据库返回状态(通过设置mainDBContext.Locations.MergeOption = MergeOption.OverwriteChagens
),但由于身份映射,您当前的修改将丢失。
答案 1 :(得分:1)
我不确定你的问题究竟是什么,但我认为你必须知道这一点:
这种查询始终返回提交到数据库的数据。当您更改代码中的某些实体但未将其提交到数据库时,LINQ查询将从数据库中查询数据,而不进行代码更改。
LINQ查询使用延迟执行,因此您的“查询”变量不是结果列表,它只是每次需要结果时评估的查询定义。您应该添加.ToList()
来评估该查询,并获取该特定代码行中的结果列表。
.ToList()
的示例:
var query = (from location in mainDBContext.Locations
where location.InUse == true
select location).ToList();
答案 2 :(得分:1)
我自己也碰到了同样的事情。它有点乱,但另一种选择是检查本地缓存。您可以这样做,例如:
var query = from location in mainDBContext.Locations.Local
where location.InUse == true
select location;
这将仅使用未保存到数据库的本地缓存。本地和数据库查询的组合应该可以让您获得所需的内容。