man*_*099 4 .net c# linq expression entity-framework
有人能告诉我为什么我不能以这种方式从Entity Framework中的MS SQL数据库中选择新对象:
public static Expression<Func<LeaveDay, bool>> IsInDatesRange(DateTime startDate, DateTime endDate){
return ld => ld.StartDate <= endDate && ld.EndDate >= startDate;
}
this.ObjectContext.People.Select(p => new NewPeopleObject
{
Guid = p.Guid,
FirstName = p.FirstName,
LastName = p.LastName,
LeaveDays = p.CalendarData.LeaveDays.AsQueryable()
.Where(LeaveDayExpressions.IsInDatesRange(startDate, endDate))
.Select(ld => new LeaveDaySummary
{
StartDate = ld.StartDate,
EndDate = ld.EndDate,
})
})
Run Code Online (Sandbox Code Playgroud)
没有AsQueryable()我无法编译应用程序,因为LeaveDayExpressions.IsInDatesRange是静态表达式.我尝试只传递Func to Where子句但它抛出内部.NET Framework数据提供程序错误1025.使用Expression和AsQueryableon LeaveDays我得到此异常:
代码应该无法访问
人是ObjectSet一个CalendarData对象的集合,People并且CalendarData有一EntityCollection组LeaveDays.
NewPeopleObject是一个具有很少属性和IEnumarable LeaveDaySummaries集合的类.
如果不将Wherelinq解析为sql错误,我该怎么做才能将Expression传递给子句?
我无法测试确切的情况下(ObjectContext,ObjectSet等表明一些老的EF版本),但是我能够重现最新EF6.1.3上述两种运行时异常(使用DbContext和DbSet)为好.
让我们忘记Func方法 - EF需要将查询转换为SQL,因此Expression是必须的.这又需要AsQueryable().到现在为止还挺好.
问题是EF不喜欢表达式树中的自定义方法 - 它通常没有顶级方法的问题,但肯定存在嵌套调用的问题,如样本中(有问题的表达式是外部选择表达式的一部分).
我不知道为什么,但在大多数情况下(包括这个和可能的话)将表达式放在查询之外的局部变量中并在里面使用它解决了问题:
var leaveDayPredicate = LeaveDayExpressions.IsInDatesRange(startDate, endDate);
var result = this.ObjectContext.People.Select(p => new NewPeopleObject
{
Guid = p.Guid,
FirstName = p.FirstName,
LastName = p.LastName,
LeaveDays = p.CalendarData.LeaveDays.AsQueryable()
.Where(leaveDayPredicate)
.Select(ld => new LeaveDaySummary
{
StartDate = ld.StartDate,
EndDate = ld.EndDate,
})
});
Run Code Online (Sandbox Code Playgroud)
对于更高级的场景(比如使用外部表达式中的某些表达式),您可能需要一些表达式处理库,例如LINQKit Invoke/Expand/ AsExpandable自定义扩展方法等.
| 归档时间: |
|
| 查看次数: |
920 次 |
| 最近记录: |