实体框架:查询多个类型

时间:2018-02-27 10:31:18

标签: inheritance entity-framework-6 table-per-hierarchy

我有一个带继承的EF6代码优先模型,例如:

[Table("Things")]
abstract class AbstractThing
{
   public int ThingId { get; set; }
   public string Color { get; set; }
}

class Car : AbstractThing
{
   public string Brand { get; set; }
}

class Balloon : AbstractThing
{
   public double Price { get; set; }
}

class Animal : AbstractThing
{
   public int LegCount { get; set; }
}

我使用table-per-hierarchy,所以我的" Things"表格将包含以下列:

  • ThingId:int
  • 颜色:字符串
  • 品牌:string
  • 价格:双倍
  • LegCount:int
  • Discriminator:string

现在,我想查询特定类型的内容,但这个类型列表是动态的。例如。我想要所有红色的东西,汽车或气球。在SQL中很容易完成,因为我可以编译where Discriminator in ('Car', 'Ballon')子句。

这里的问题是,据我所知,在EF Linq2SQL中按类型过滤的唯一方法是使用.OfType方法(或使用特定的集合)。但后来我找回了只包含该类型的过滤列表,我不能使用' OR'或者' IN'条款。我无法在没有明确查询每一组并建立联合的情况下弄清楚如何做到这一点:

var queryable = Enumerable.Empty<Thing>().AsQueryable();

if (typesRequested.Contains(typeof(Car)))
{
   queryable = queryable.Union(context.Things.OfType<Car>());
}
if (typesRequested.Contains(typeof(Balloon)))
{
   queryable = queryable.Union(context.Things.OfType<Balloon>());
}
if (typesRequested.Contains(typeof(Animal)))
{
   queryable = queryable.Union(context.Things.OfType<Animal>());
}

在我的实际模型中,我有更多的继承类型,这种方法不太可行。我现在的解决方法是使用自定义&#39;类型&#39;与“判别器”一起冗余的列。列,但这很容易出错并产生锅炉板代码。

有没有其他方法可以动态限制查询只返回一组特定的类型?

1 个答案:

答案 0 :(得分:0)

使用EF Core似乎可以实现:'Discriminator'属性现在可以作为 Shadow属性使用。 (https://docs.microsoft.com/en-us/ef/core/modeling/relational/inheritance#configuring-the-discriminator-property

即:

var types = typesRequested.Select(x => x.Name).ToArray();
var filteredByType = context.Things.Where(tng => 
                 types.Contains(EF.Property<string>(tng, "Discriminator")));