实体框架代码第一个4.3/LINQKit相关表的谓词

Pit*_*DBA 5 linq-to-entities entity-framework entity-framework-4 ef-code-first

我正在使用Entity Framework 4.3.1和Code First方法.另外,我使用LinqKit以便使用PredicateBuilder.

如果我有这样的表:

位置,TimeZone(许多:1)

..我希望有这样的东西:

Expression<Func<TimeZone, bool>> pred = PredicateBuilder.True<TimeZone>();
pred = pred.And(tz => tz.TimeZoneCode == "EST");

List<Location> locations = context.Locations
    .AsExpandable().Where(pred)
    .Select(loc => loc).ToList();
Run Code Online (Sandbox Code Playgroud)

这不起作用,因为谓词是为了接受TimeZone而构建的,但Where()方法接收一个Location.

我可以像这样重写谓词,但我不想这样做,因为我想要一个为特定类型创建谓词的谓词工厂(我不想以这种方式使用Navigator属性):

Expression<Func<Location, bool>> pred = PredicateBuilder.True<Location>();
pred = pred.And(loc => loc.TimeZone.TimeZoneCode == "EST");
Run Code Online (Sandbox Code Playgroud)

我可以使用什么语法(如果有的话)来使用第一个示例中构造的谓词,它使用TimeZone,而不是让它获取位置并通过导航属性遍历树(因为这不太可重复使用).如果有一种方法可以首先利用EF对导航属性的知识,并且能够使用作用于导航属性类型的谓词,那将是很好的.

Gri*_*inn 5

经过大约一周的努力,我发现你实际上可以做到这一点.步骤是:

  1. 定义谓词,它是内部属性的查询(subPredicate)
  2. InvokesubPredicate从另一个谓词内(predicate),对父对象的属性.
  3. Expandpredicate在你的Where条款中使用它.

这是您的示例的修订代码:

var subPredicate = PredicateBuilder.True<TimeZone>();
subPredicate = subPredicate.And(tz => tz.TimeZoneCode == "EST");

var predicate = PredicateBuilder.True<Location>();
predicate = predicate.And(l => subPredicate.Invoke(l.TimeZone));

List<Location> locations = context.Locations
    .AsExpandable().Where(pred.Expand())
    .Select(loc => loc).ToList();
Run Code Online (Sandbox Code Playgroud)