我使用实体框架4.3.1守则第一种方法。 另外,我使用LinqKit以便使用PredicateBuilder。
如果我有像这样的表:
地点,时区(很多: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();
这是不行的,因为断言是建立在接受的时区,但其中()方法接收位置。
我可以重写,像这样的断言,但我不想,因为我想有一个谓语工厂,为特定类型的创建谓词(我不想以这种方式来使用导航性能):
Expression<Func<Location, bool>> pred = PredicateBuilder.True<Location>();
pred = pred.And(loc => loc.TimeZone.TimeZoneCode == "EST");
我可以使用什么样的语法(如果有的话)使用谓词作为第一个例子,它需要一个时区,而不是把它拿一个位置,并通过导航属性在树内(因为这是可重复使用的较少)构成。 如果有利用的知识EF有大约在首位的导航性能,并能够使用谓词范围的导航属性的类型的方式这将是很好。
大约一个星期的挣扎之后,我发现,你其实可以做到这一点。 步骤如下:
- 定义一个谓词是你的内在属性的查询(
subPredicate
) -
Invoke
该subPredicate
从另一个谓词(内predicate
),对父对象的属性。 -
Expand
你的predicate
您在使用时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();
只是为了更新这样的:事实证明,这些类型谓词的目的是筛选的主要实体。 心理概念是:决定你想返回的实体,并返回它们。 EF显然不适合这种对儿童实体深谓词应用。
一个人(我不记得在哪里)做出了很大的一点:如果孩子们预加载,你不会指望一个部分负载的集合。 因此,它是没有意义有发票实体,例如,但只有发票行的一半。
我想实现的线沿线的更EXISTS(),或在(),在那里你可以说“给我哪里有发票行的产品类型‘螺母’和‘螺栓’的所有发票”。 这是可行的,但您可能必须应用LINQ或撰写自己的对象。 EF的意图开箱是交给你的发票,然后你可以懒洋洋地或急切地加载发票行,但不使用它们作为直接从数据库中的过滤器。
有一些结构,我看到有所建树接近,但语法变得非常难以管理非常迅速。
别打了市政厅。