错误:“指定的 LINQ 表达式包含对与不同上下文关联的查询的引用”
Posted
技术标签:
【中文标题】错误:“指定的 LINQ 表达式包含对与不同上下文关联的查询的引用”【英文标题】:Error: "The specified LINQ expression contains references to queries that are associated with different contexts" 【发布时间】:2011-11-12 01:45:00 【问题描述】:我从一个包含来自两个不同 edmx 文件的两个表的 LINQ 查询中收到标题中显示的错误。这是查询:
var query = (from a in db1.Table1
join b in db1.Table2 on a.Id equals b.Id
orderby a.Status
where b.Id == 1 && a.Status == "new"
select new
Id = a.Id,
CompanyId = (from c in db2.Company
where s.Id == a.Id
select
new c.CompanyId )
);
db1
和 db2
是与两个不同 edmx 文件相关联的上下文。我该如何克服这个错误?
【问题讨论】:
【参考方案1】:您必须执行两个数据库查询:
var IDs = (from a in db1.Table1
join b in db1.Table2 on a.Id equals b.Id
orderby a.Status
where b.Id == 1 && a.Status == "new"
select new a.Id).ToArray();
var query = from c in db2.Company
join a in IDs on c.Id equals a.Id
select new Id = a.Id, CompanyId = c.CompanyId ;
.ToArray()
至关重要。它阻止 EF 尝试执行组合查询(由于它使用两个不同的上下文,这将失败)。如果您希望保持延迟加载,可以使用.AsEnumerable()
。
还有你的后续问题:
还有其他方法可以使 LINQ 查询更加优化吗?那是, 在单个 LINQ 查询本身中执行操作?
为了让您的原始查询成功运行,它必须仅使用一个数据上下文,这意味着所有数据必须可从单个 EDMX 获得,这反过来意味着单个连接字符串。有几种方法可以实现:
如果两个表都在同一个数据库中,请将它们都添加到单个 EDMX。 如果它们在不同的数据库上但在同一个实例上,请在其中一个数据库上创建一个视图,从另一个数据库的表中选择,然后将本地表和视图添加到单个 EDMX。 如果它们位于不同的实例/服务器上,则创建一个链接服务器,然后在链接服务器上创建表的视图,然后将本地表和视图添加到单个 EDMX。【讨论】:
Allon,你介意看看我的问题,***.com/q/26517596/2112866 吗?两张表都是相同的 EDMX。非常感谢。 非常清楚地解释了解决方案和可能的替代方案 - 谢谢。 这里最好使用Contains
。在较旧的 EF 版本中,join
将生成一个可怕的查询,在以后的(核心)版本中不支持。【参考方案2】:
您需要将第二个表添加到第一个上下文的模型中。如果这是在多个数据库中,您需要使用 Linq to Objects 连接在客户端进行辅助查找。
【讨论】:
感谢您的回复。能否请您给我更多详细信息。 我需要更多关于您为什么使用多个 EDMX 文件的详细信息才能知道该走哪条路。【参考方案3】:您必须手动创建 EntityConnection,其中填充了您要使用的所有 .EDMX 的资源。 您可以通过添加与 app.config 的连接或以编程方式来实现。 然后您可以使用准备好的 EntityConnection 创建 DBContext。
方法一)
<add name="MyConnection"
connectionString="metadata=res://*/Entities.ModuleA.csdl|res://*/Entities.ModuleA.ssdl|res://*/Entities.ModuleA.msl|res://*/Entities.ModuleB.csdl|res://*/Entities.ModuleB.ssdl|res://*/Entities.ModuleB.msl;
provider=System.Data.SqlClient;provider connection string="MyConnectionString""
providerName="System.Data.EntityClient" />
using (EntityConnection oEntityConnection =
new EntityConnection("name=MyConnection"))
using(DbContext oDBContext = new DbContext(oEntityConnection))
//your code - available are entities declared in Entities.ModuleA and Entities.ModuleB
方法 b)
using (EntityConnection oEntityConnection =
new EntityConnection(new MetadataWorkspace(
new string []
"res://Entities.ModuleA/",
"res://Entities.ModuleB/"
,
new Assembly[]
Assembly.GetAssembly(typeof(Entities.ModuleA.AnyType)),
Assembly.GetAssembly(typeof(Entities.ModuleB.AnyType))
)))
using(DbContext oDBContext = new DbContext(oEntityConnection))
//your code - available are entities declared in Entities.ModuleA and Entities.ModuleB
【讨论】:
以上是关于错误:“指定的 LINQ 表达式包含对与不同上下文关联的查询的引用”的主要内容,如果未能解决你的问题,请参考以下文章
错误:“指定的 LINQ 表达式包含对与不同上下文关联的查询的引用”[重复]
(Linq/Lambda) 使用 2 个 DBContext 连接 2 个或更多表
远程服务器返回错误: 404错误远程服务器返回错误:500错误 HttpWebResponse远程服务器返回错误:(404500) 错误。