我最近从Entity Framework 5升级到Entity Framework 6.1.3。
以下使用相同连接的多个上下文的代码在EF5之前工作正常:
var ref = new Firebase("https://dinosaur-facts.firebaseio.com/dinosaurs");
ref.orderByChild("height").equalTo(0.6).on("child_added", function(snapshot) {
console.log(snapshot.key());
});
在EF6中,我收到:
指定的LINQ表达式包含对查询的引用 与不同的背景相关联。描述:未处理 在执行当前Web请求期间发生异常。 请查看堆栈跟踪以获取有关错误的更多信息 它起源于代码。
异常详细信息:System.NotSupportedException:指定的LINQ 表达式包含对与之关联的查询的引用 不同的背景。
实体框架中的哪些内容已更改以阻止其工作?无论如何我可以在不改变代码的情况下使用它吗?
答案 0 :(得分:2)
将第一行从plink.exe
更改为.AsEnumerable()
。
答案 1 :(得分:1)
https://msdn.microsoft.com/en-us/data/hh949853.aspx#_Query_Plan_Caching
根据此文档,对EF 6中的Contains
处理进行了更改,以优化生成基础SQL查询的方式。
只是在黑暗中拍摄而不看EF6的代码:
IEnumerable通常是延迟执行,在您以某种方式引用数据之前不会命中数据库。从框架的角度来看,这不是整数或长整数列表,而是需要在不同上下文中执行的查询。由于它位于不同上下文中的查询中间,因此SQL解析器可能无法使用新的处理方式解析它。 IEnumerable是Queryable和loaded之间的一种中间状态。我猜他们为优化所做的任何更改都不再执行未完成的查询,如果引用的对象不是上下文的一部分,它就会立即短路到异常,无论它是什么。
这也是将其更改为List()
的原因。您正在处理基元列表而不是未解析的查询。
他们为什么要做出改变?我想他们有他们的理由(甚至超越了优化)。我能想到的是,它可以防止查询生成部分修改IEnumerable的加载状态,以消除可能不需要的副作用。
答案 2 :(得分:0)
您可以添加ToDictionary()
:
var Ids = (
from x in MyDbContext.MyObject.Select()
where x.Contains(x.Id)
select x
).ToDictionary(x => x.Key).Keys.ToList();
var myObjects = (
from y in MyDbContext2.MyObject
where y => Ids.Contains(y.Id).ToList()
).ToList();
return myObjects;