【问题标题】:Entity Framework : Filter query by property of a child type实体框架:按子类型的属性过滤查询
【发布时间】:2017-10-30 11:03:26
【问题描述】:

我的模型如下

class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
}

class Employee : Person
{
    public string Dep { get; set; }
}

class Client : Person
{
    public string Type { get; set; }
}

现在我想通过Employee的属性查询Person如下

context.Set<Person>().Where(x => ((Employee)x).Dep == "dep").ToList();

但我收到以下错误

无法将类型“DomainModel.Person”转换为类型 'DomainModel.Employee'。 LINQ to Entities 仅支持转换 EDM 原始类型或枚举类型。

我知道我可以简单地使用

context.Set<Employee>().Where(x => x.Dep == "dep").ToList();

但问题是我使用通用搜索控件,该控件只能处理要搜索的一种类型,搜索条件作为确定类型的 lambda 表达式传递给该控件,搜索语句也由搜索控件作为 lambda 表达式,然后作为谓词传递给 Where 方法,现在我想使用此搜索控件同时搜索 Employee 和 Person,因为搜索控件只能处理一种类型我将父类型传递给它Person,这样我就可以在搜索中访问它的所有子类型属性,但我遇到了上面提到的问题。有什么想法吗?

【问题讨论】:

  • 您可以为您的搜索控件发布一些代码吗?
  • 这是一个非常大的代码块,但在概念上它几乎与此链接中的搜索控件palmmedia.de/blog/2012/2/18/…
  • Person 类是否是 EF 继承(TPH、TPT 或 TPC)的一部分?还是只是一个基类?换句话说,context.Set&lt;Person&gt;().ToList() 有效吗?
  • 继承类型为TPH。是的,它确实有效。

标签: c# entity-framework children


【解决方案1】:

当涉及到 EF 继承时,LINQ to Entities 查询不支持cast 运算符。不过is和as运算符是完全支持的,所以这样的过滤器的正确写法是这样的:

context.Set<Person>()
    .Where(x => x is Employee && (x as Employee).Dep == "dep")
    .ToList();

【讨论】:

  • Func 类型的表达式呢?例如,当我在 Include 中尝试 ((x as Employee).MyRefType) 时,它会抛出异常并说“指定的包含路径无效,员工没有声明名为 MyRefType 的导航属性”,我该如何解决这个问题?
  • 不幸的是,EF6 和最新的 EF Core 都没有包含派生实体导航属性的解决方案。例如,请参阅 stackoverflow.com/questions/45787939/… 以了解一种解决方法,但它并不普遍适用,需要查询具体化和后处理。
猜你喜欢
  • 2012-10-11
  • 2018-03-18
  • 1970-01-01
  • 1970-01-01
  • 2015-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多