错误:“指定的 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 )
           );

db1db2 是与两个不同 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=&quot;MyConnectionString&quot;"
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 表达式包含对与不同上下文关联的查询的引用

指定的 LINQ 表达式包含对与不同上下文关联的查询的引用

(Linq/Lambda) 使用 2 个 DBContext 连接 2 个或更多表

远程服务器返回错误: 404错误远程服务器返回错误:500错误 HttpWebResponse远程服务器返回错误:(404500) 错误。

Pig 安装错误:错误 pig.Main:错误 2998:未处理的内部错误