web-dev-qa-db-ja.com

エンティティフレームワークを使用して2つのデータベースのテーブルを結合する

ASP.NET MVC 4 Webアプリケーションに取り組んでいます。私は Entity Framework をデータアクセスレイヤーとして使用しており、データベースの最初のアプローチ(.edmxファイル)。

現在、2つの異なるデータベース内で定義されている結合テーブルに問題があります(つまり、2つの.edmxファイル)。

たとえば、テーブルを結合したい場合は、次のクエリを実行しています。

public ActionResult AutoComplete(string term)
{
   var tech = repository.AllFindTechnolog(term).Take(100);//Call to the first database
   var resources = repository.GetResources(tech.Select(a => a.IT360ID.Value).ToArray(), false);//call to the second database

   var query = from techItems in tech
         join resourcesItems in resources
         on techItems.IT360ID.Value equals resourcesItems.RESOURCEID // join based on db2ID
         orderby techItems.PartialTag
         select new //code goes here

   return Json(query, JsonRequestBehavior.AllowGet);
}

データベースへの2つの個別の呼び出しと、アプリケーションサーバー内の結合がありますが、これは最適なパフォーマンス指向のソリューションではありません。理想的には、結合は完全にデータベースエンジン内で行われます。

ストアドプロシージャによって、サーバー上の純粋に異なるデータベースのテーブルを結合できることはわかっていますが、コードの保守性とテスト性が低下するため、SPを使用しません。

それで、エンティティフレームワークを使用して結合を実行し、単一のデータベース結合を生成できるソリューションを探していますか?

12
john Gu

単一のデータベース呼び出しでそれを実行したい場合は、別個のデータベースの2つのテーブルを結合するデータベースにビューを作成する必要があります。ビューが作成されたら、それを単一のオブジェクトとしてEFに追加できます。これをさらに操作して、クエリをオフにすることができます。ビューは基本的にテーブルであり、簡単に保守可能で、強く型付けされたモデルにバインドするのが簡単です。

別の方法として、投稿したのと同じように、個別に.edmxファイルを作成し、それらを結合します。はい、データベースへの呼び出しは2つありますが、それほど高価ではなく、おそらく違いに気付かないでしょう。

using(var db = new MyEntities())
using (var db2 = new MyEntities2())
{
   var one = db.Table1.AsEnumerable();
   var two = db2.Table2.AsEnumerable(); 

   var result = from o in one
                join t in two on o.Id equals t.Id
                // blah blah

}
4
CSharper

@CSharperの答えは近いです。 @Oliverがコメントで述べたように、IEnumerableはテーブルをアプリケーションメモリにロードし、大規模なデータベースがある場合にクラッシュを引き起こします。

解決策は、LINQで呼び出すことができるIQueryableを使用することです。これにより、はるかに高速なSQLが生成されます。

// This is a generic method, modify to your needs
public ActionResult Details(int? id)
   var one = db.Table1.AsQueryable();
   var two = db2.Table2.AsQueryable(); 

   // since you're using MVC EF, I assume you want to put this in a viewmodel 
   // (in this case ObjectCombined)
   // assume "id" is passed as parameter 
   Object1 result1 = (from o in one where one.id == id select o).Single();
   Object2 result2 = (from t in two where t.id == o.id select t).Single();
   ObjectCombined result = new ObjectCombined(result1, result2);
   return View(result);
}
3
chakeda

ビューまたはストアドプロシージャを作成すると、SQLステートメントでクロスデータベースクエリを実行できます。資格情報が両方のデータベースでDMLまたはDDLを実行できることを確認してください。それ以外の場合は、usingステートメント内でdbエンティティを宣言しないときにlinqバグが発生しないことを確認する入れ子になったusingエンティティを試してください。

0
CyberNinja

データベースで synonym を使用することを検討することをお勧めします。たとえば、techテーブルが配置されているデータベース内のリソーステーブルのシノニムを作成できます。これにより、2つのEDMXファイルを保持する必要がなくなります。代わりに、単一のEDMXファイルを作成し、techテーブルをリソーステーブルのシノニムに結合するだけで、できあがりです。

更新:同義語を使用している場合は、EDMXファイルをEntity Frameworkで機能させるために、EDMXファイルに追加の作業が必要になることに注意してください。これが ブログ投稿 で、それを機能させるプログラマーが出したものです。これが、元の stackoverflow の質問です。

幸せなコーディング!!! :)

0
Gjohn