7

次のエンティティがあるとしましょう

public abstract class Animal
{
    public int Id {get;set;}
}

public class Cat : Animal
{
}

public class Dog : Animal
{
}

インスタンスを作成せずにエンティティのタイプを判別することは可能ですか?

var id = 1;
var type = context.Animals.GetTypeOfAnimal(id)

public static Type GetTypeOfAnimal(this ObjectSet<Animal> source, int id)  
{
    // What shall I do here, I dont want to fetch the instance at this point...
    var animal = source.First(a => a.Id == id);
    return animal.GetType();
}

次の方法を使用して考えた1つの解決策...

public static Type GetTypeOfAnimal(this ObjectSet<Animal> source, int id)  
{
    var info = source.Where(a => a.Id == id).Select(a => new {IsDog = a is Dog, IsCat = a is Cat}).First();

    if(info.IsDog) return typeof(Dog);
    if(info.IdCat) return typeof(Cat);

    return null;
}
4

1 に答える 1

2

データベースへのクエリなしでこの情報を取得する方法はありません。TPT を使用しています - データベースに動物、犬、猫のテーブルが含まれていることを意味します。データベース内の継承は、Animal と Dog の間、および Animal と Cat の間の 1 対 1 の関係によってモデル化されています。最低限しなければならないことは、その Id について Animal テーブルと Dog テーブルの両方にクエリを実行することです (それらの 1 つにのみ存在できます)。最初の問題は、EF は (単一のテーブルにマップされた部分だけでなく) エンティティ全体でのみ機能するため、これらのテーブルを EF で直接クエリできないことです。直接 SQL を使用する必要があります。2 つ目の問題は、このソリューションの脆弱性です。新しい派生エンティティを追加する場合は、このクエリを修正する必要があります (例でも同じことが起こります)。

TPT クエリが遅い理由は、EF がすべての継承ツリーをクエリする必要があるためAnimalです。.NET 4.5 では、TPT 継承ツリーのクエリのパフォーマンスが向上していますが、構造全体をクエリする必要があるだけなので、クエリには影響しません。DogAnimalCat

于 2012-06-27T08:58:24.070 に答える