使用每种类型继承的表时返回实体类型

Roh*_*est 7 c# entity-framework-4

假设我有以下实体

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

public class Cat : Animal
{
}

public class Dog : Animal
{
}
Run Code Online (Sandbox Code Playgroud)

是否可以在不创建实例的情况下确定实体的类型.

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();
}
Run Code Online (Sandbox Code Playgroud)

我考虑使用以下方法的一个解决方案......

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;
}
Run Code Online (Sandbox Code Playgroud)

Lad*_*nka 2

如果不查询数据库就无法获取此信息。您正在使用 TPT - 这意味着数据库包含动物、狗和猫表。数据库中的继承是通过Animal和Dog之间以及Animal和Cat之间的一对一关系来建模的。您至少需要做的是查询 Animal 和 Dog 表中的该 ID(它只能存在于其中之一中)。第一个问题是您无法直接使用 EF 查询这些表,因为 EF 只能处理整个实体(而不仅仅是映射到单个表的部分) - 您必须使用直接 SQL。第二个问题是该解决方案的脆弱性。如果添加新的派生实体,则必须修复此查询(您的示例也会发生同样的情况)。

TPT 查询速度慢的原因是 EF 必须查询所有继承树 = 在您的情况下Animaljoin with Dogconcatenated with Animaljoined with Cat。.NET 4.5 在查询 TPT 继承树方面有一些性能改进,但这不会影响您的查询,因为它只需要查询整个结构。