C# Linq到SQL内部.NET Framework数据提供程序错误1025
有人能告诉我为什么不能用这种方式从Entity Framework中的MS SQL数据库中选择新对象吗:C# Linq到SQL内部.NET Framework数据提供程序错误1025,c#,.net,linq,entity-framework,expression,C#,.net,Linq,Entity Framework,Expression,有人能告诉我为什么不能用这种方式从Entity Framework中的MS SQL数据库中选择新对象吗: public static Expression<Func<LeaveDay, bool>> IsInDatesRange(DateTime startDate, DateTime endDate){ return ld => ld.StartDate <= endDate && ld.EndDate >= startDate;
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,
})
})
公共静态表达式是数据范围(DateTime startDate、DateTime endDate){
返回ld=>ld.StartDate=StartDate;
}
this.ObjectContext.People.Select(p=>newNewPeopleObject
{
Guid=p.Guid,
FirstName=p.FirstName,
LastName=p.LastName,
LeaveDays=p.CalendarData.LeaveDays.AsQueryable()
.Where(LeaveDayExpressions.isindateRange(开始日期,结束日期))
.选择(ld=>new LeaveDaySummary
{
StartDate=ld.StartDate,
EndDate=ld.EndDate,
})
})
如果没有AsQueryable()
我就无法编译应用程序,因为LeaveDayExpressions.isindateRange
是静态表达式。我曾尝试将only Func传递给Where
子句,但它抛出内部.NET Framework数据提供程序错误1025。在LeaveDays
上使用Expression和AsQueryable
,我得到了以下异常:
应该无法访问的代码
人员是ObjectSet
集合,其中一个CalendarData
对象位于People
上,并且CalendarData
具有EntityCollection
集合的LeaveDays
NewPeopleObject
是一个属性很少的类,并且IEnumarable
leavedaysumeries
集合
如何将表达式传递到
Where
子句而不解析linq to sql错误?我无法测试确切的情况(ObjectContext
,ObjectSet
等。指示一些较旧的EF版本),但我能够在最新的EF6.1.3中重现上述两个运行时异常(也使用DbContext
和DbSet
)
让我们忘记Func
approach-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,
})
});
对于更高级的场景(例如使用外部表达式中的某些内容的表达式),您可能需要一些表达式处理库,例如
Invoke
/Expand
/AsExpandable
自定义扩展方法等。据我所知,您没有向我们展示如何定义LeaveDayExpressions。如果看不到这一点,就很难提供帮助。我在上面编辑了我的代码。是的,这仍然不足以说明问题有意义。您正在尝试创建一个扩展方法吗?那么语法应该类似于。Where(L=>L.isindadesrange(startDate,endDate))
它不是扩展,它是一个用于在数据库查询中过滤LeaveDays的表达式。它可以与ObjectSet
类似于this.ObjectContext.LeaveDays.Where(LeaveDayExpressions.IsInDadesRange(startDate,endDate))
但它不能与EntityCollection一起工作,我不知道为什么。我想说的是,你不能在实体框架中使用它。