2つの異なるedmxファイルからの2つのテーブルを含む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
は、2つの異なるedmxファイルに関連付けられているコンテキストです。このエラーを解決するにはどうすればよいですか?
2つのデータベースクエリを実行する必要があります。
_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が結合クエリを実行しようとするのを防ぎます(2つの異なるコンテキストを使用するため失敗します)。遅延読み込みを続けたい場合は、.AsEnumerable()
を使用できます。
あなたのフォローアップの質問:
LINQクエリをさらに最適化する他の方法はありますか?つまり、単一のLINQクエリ自体でアクションを実行しますか?
元のクエリを正常に実行するには、単一のデータコンテキストのみを使用する必要があります。つまり、すべてのデータが単一のEDMXから利用可能である必要があり、これは単一の接続文字列を意味します。それを実現する方法はいくつかあります。
最初のコンテキストのモデルに2番目のテーブルを追加する必要があります。これが複数のデータベースにある場合、Linq to Objects結合を使用して、クライアント側でセカンダリルックアップを実行する必要があります。
使用するすべての.EDMXのリソースで満たされたEntityConnectionを手動で作成する必要があります。 app.configに接続を追加するか、プログラムで接続して追加できます。次に、準備されたEntityConnectionを使用してDBContextを作成できます。
方法a)
<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
}
}