2016-09-17 19 views
1

私はC#でEF(コードファースト)を使用してデータ分析プロセスを作成しています。データモデルには、約12の関連するクラスが含まれます。これらのほとんどは既存のデータベースのテーブルに直接対応していますが、いくつかの主要な読み取り専用オブジェクトタイプは、実際は複雑な複数ステップのSQLクエリの製品です。クエリのビューまたはストアドプロシージャを作成できません。SQLクエリ結果をEntity Frameworkのオブジェクトとして使用するにはどうすればよいですか?

私はDbSet.SqlQuery()のようなものを使用して、これらのクエリ結果をEFオブジェクトにロードし、EFのORM機能を利用して残りのオブジェクトグラフと関連付けることができるようにしたいと考えています。

DbSetがデータベースからクエリベースのオブジェクトを移入しようとすると、EFのSQL SELECTコードをオーバーライドする方法が必要だと思います。これは可能ですか?よりよい代替アプローチがありますか?

+0

複数のコンテキストを使用していれば可能です。特定のコンテキスト・インスタンスがテーブルをヒットしたときに計算されたクエリと最終的には外部キー制約を決定するので、照会するプロパティとその外部キー制約の間にマッピングする別のコンテキストを使用できます。コンテキストを切り替えると、メモリに参加する必要があります。 – DevilSuichiro

+0

あなたはインターセプタを見ましたか? – Monah

+0

@DevilSuichiroはデビルに感謝しますが、なぜ私はあなたに次の文脈が役立つのかはわかりません。 –

答えて

0

私のために働く方法を見つけましたが、それはハッキーです。

たとえば、Fooは、SQLで明示的に書き込み、読み取り専用のEFオブジェクトグラフでオブジェクトとして使用する高価なクエリ結果に対応するpocoクラスです。 Fooには、外部キーとナビゲーションプロパティが含まれています。私のdbContextはFoosと呼ばれるDbSetを持っています。

// Pre-req: prevent EF from trying to sync model with db, since Foos doesn't map to a db table. 
public FooDbContext() 
{ 
    Database.SetInitializer<FooDbContext>(null); 
} 

// load the query data with SqlQuery() and Attach() 
var foos = db.Foos.SqlQuery("<hand written SQL SELECT>", parameters); 
foreach(var foo in foos) db.Foos.Attach(foo); 

// Subsequently reference the data with .Local to prevent db hits (which would fail, since no Foo table in db.) 
var result = db.Foos.Local.Select(...); 

関連オブジェクトを明示的に読み込む必要がありますが、すべての関連付けが自動的に行われます。たとえば、BarにFooで1対多があり、FooにBarIdプロパティ(およびBarナビゲーションプロパティ)があり、BarクラスにFoosの観測可能なコレクションがあるとします。バーは、デシベルのルックアップテーブルとして格納されている場合、私はちょうどdb.Bars.Load()、またはそれ以上のフィルターのようなもの行うことができます:

var barIds = db.Foos.Local.Select(f => f.BarId).Distinct().ToArray(); 
db.Bars.Where(b => barIds.Contains(b.barId)).Load(); 

は、それから私はFoo.BarまたはBar.Foos、すべての作品を使用することができます。

0

任意のクエリをストアドプロシージャに書き込むことはできますか?その場合、Entityフレームワークを使用して関数にマップできます。

+0

残念ながら、私はこれのためにストアドprocsまたはビューを使用することはできません。しかし、たとえできたとしても、結果がEFによって「追跡」されているようには見えません。私の場合は、オブジェクトグラフの残りの部分との関係が設定されています。 –