Entity Framework - Union引起“无法创建类型为...的常量值”

10

为了选取所有处于活动状态的Scheduling,我有如下代码:

var allSchedulesOnALine = CurrentUser.Lines.SelectMany(o => o.Scheduling).Where(o => o.Active);
var allSchedulesUnscheduled = Entities.SchedulingSet
    .Where(o => o.Line == null && o.Site.Id == CurrentUser.Site.Id &&
           o.Factory == CurrentUser.Factory && o.Active);

IEnumerable<Scheduling> allSchedules = allSchedulesUnscheduled.Union(allSchedulesOnALine);
foreach(Scheduling schedule in allSchedules.OrderBy(o => o.Ordering))
{
    //Do Stuff
}

(Factory 是一个 int)

当我运行这段代码时,在 foreach 行会出现以下晦涩的错误:

无法创建类型为'System.Collections.Generic.IEnumerable`1'的常量值。只支持原始类型('如Int32、String和Guid')在此上下文中。

奇怪的是,我可以分别枚举 allSchedulesOnALineallSchedulesUnscheduled。更奇怪的是,如果我重新排列联合:

IEnumerable<Scheduling> allSchedules = allSchedulesOnALine.Union(allSchedulesUnscheduled);

它运行良好!

有没有人知道为什么会出现这种情况?我是不是漏掉了什么重要的东西,还是这是一个bug?

我应该提到我正在使用Entity Framework 3.5。目前我们无法使用EF4 - 它超出了我的控制: \


我认为错误信息表明EF无法将您的联合语句翻译成SQL,但我不确定原因。CurrentUser.Lines.SelectMany(o => o.Scheduling).Where(o => o.Active)是否可能没有使用延迟执行?如果是这样,那么它可能解释了为什么您可以按一个方向排序,而不能按另一个方向排序--一个在内存中运行,另一个试图完全在SQL中运行。你有什么想法吗? - Pandincus
1个回答

13

你的"reordering"中调用了两个不同的方法。

你没有展示allSchedulesOnALineallSchedulesUnscheduled的类型,但我猜allSchedulesOnALineIEnumerable<Schedule>类型,而allSchedulesUnscheduledIQueryable<Schedule>类型。

因此,当你调用Queryable.Union时,你要求EF将表达式转换为SQL。但你传递的参数IEnumerable<Schedule>类型,它无法将其转换为查询。

另一方面,当你调用Enumerable.Union时,你要求LINQ to Objects在内存中执行整个操作,这虽然可能会慢一些,但仍然有效。

所以行为不同的原因是你调用了两个完全不同的方法,它们做不同的事情,但恰巧拥有相同的名称。 不,这不是一个错误。


这一定是你第十二次在这里帮我解决EF问题了,包括我想这个确切的问题之前(呃)。再次感谢你,Craig! - BlueRaja - Danny Pflughoeft

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接