2010-12-06 8 views
2

すべてのレコードが同じテーブルにあるように、識別子フィールドで継承を実装しました。私のbasetypeはPerson(テーブルの名前でもあります)で、DriverとPassengerはそれを継承しています。 Personへのオブジェクトコンテキストのクエリを実行すると、正しいタイプのインスタンス(ドライバとパッセンジャ)が返されます。例:EF4の継承とストアドプロシージャ

var q = from d in ctx.Person 
     select d; 

しかし、ストアドプロシージャを呼び出し、その関数の出力を型Personにマップする関数も作成します。しかし、今私はこのメソッドを実行すると、人とドライバまたは乗客のリストを取得します。

これを解決する方法は誰か、またはこれはEF4のバグですか?

答えて

1

AFAIKでは、ストアドプロシージャのマッピングを処理する際に、ディスクリミネータマッピング(例:TPH)を使用することはできません。

ストアドプロシージャを複合型またはカスタムエンティティ(たとえばPOCO)にマップする必要があり、マッピングを条件付きにすることはできません。

通常のPOCOにマップすることができますが、プロジェクトの結果が関連する派生型(手動差別)に設定されています。

例えば:

public ICollection<Person> GetPeople() 
{ 
    var results = ExecuteFunction<Person>(); // result is ObjectResult<Person> 
    ICollection<Person> people = new List<Person>(); 

    foreach (var result in results) 
    { 
     if (result.FieldWhichIsYourDiscriminator == discriminatorForDriver) 
     { 
     people.Add((Driver)result); 
     } 

     // other discriminators 
    } 

} 

あなたは、常に1つのタイプ(例えばドライバのみ)のコレクションを期待している場合、あなたは、foreachループを必要としない、あなただけの範囲を追加することができます。上記は、異なる人種の混在した袋を期待している場合のためのものです。

他の回答を見ることに興味がありますが、より良い方法がある場合は - 上記がうまくいくはずです。

+0

問題は、私のディスクリミネータフィールドがオブジェクトに公開されておらず、ライブラリを使用している開発者にそのプロパティを公開したくないためです。だから私はネイティブの解決策が必要になるのではないかと心配しています:-( –

+1

ああ、ディスクリミネータはあなたのモデルにはありません。例: 'usp_GetDrivers'(ドライバのコレクションにマップ)、' usp_GetPassengers'(乗客のコレクションにマップする)あなたはObject Contextに一つのメソッドを持つことができます。その仕事はありますか? – RPM1984