Linq to SQL Internal .NET Framework数据提供程序错误1025

时间:2015-08-25 14:38:19

标签: c# .net linq entity-framework expression

有人可以告诉我为什么我不能以这种方式从实体框架中的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,
         })
    })

没有AsQueryable()我无法编译应用程序,因为LeaveDayExpressions.IsInDatesRange是静态表达式。我尝试只将Func传递给Where子句,但它会抛出内部.NET Framework数据提供程序错误1025.使用表达式和AsQueryable LeaveDays我得到此异常:

  

代码无法访问

人是ObjectSet集合,其中一个CalendarData上有一个People个对象,CalendarData EntityCollectionLeaveDays

NewPeopleObject是一个包含少量属性和IEnumarable LeaveDaySummaries集合的类。

如果不将linq解析为sql错误,我该怎么做才能将Expression传递给Where子句?

1 个答案:

答案 0 :(得分:5)

我无法测试确切的情况(ObjectContextObjectSet等表示一些较旧的EF版本),但我能够在最新的EF6.1.3中重现上述运行时异常(使用DbContextDbSet)也是如此。

忘记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,
        })
});

对于更高级的场景(比如使用外部表达式中的某些内容),您可能需要一些表达式处理库,例如LINQKit Invoke / Expand / AsExpandable自定义扩展方法等。