Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework - Union causes "Unable to create a constant value of type.."

To select all Schedulings which are active, I have the following code:

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 is an int)

When I run this code, I get this cryptic error on the foreach line:

Unable to create a constant value of type 'System.Collections.Generic.IEnumerable`1'. Only primitive types ('such as Int32, String, and Guid') are supported in this context.

Strangely enough, I can enumerate both allSchedulesOnALine and allSchedulesUnscheduled separately. Even stranger, if I reorder the union:

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

It works fine!

Does anyone have any idea why this would happen? Am I missing something crucial, or is this a bug?

I should mention I am using Entity Framework 3.5. EF4 is not an option for us currently - it is beyond my control :\

like image 863
BlueRaja - Danny Pflughoeft Avatar asked Feb 03 '23 18:02

BlueRaja - Danny Pflughoeft


1 Answers

You're calling two different methods with your "reordering".

You don't show the types of allSchedulesOnALine or allSchedulesUnscheduled, but I'm betting allSchedulesOnALine is of type IEnumerable<Schedule> and allSchedulesUnscheduled is of type IQueryable<Schedule>.

So when you call Queryable.Union, you're asking the EF to translate the expression into SQL. But the argument you pass is of type IEnumerable<Schedule>, and it can't translate that into a query.

On the other hand, when you call Enumerable.Union, you're asking LINQ to Objects to do the whole thing in memory, which works fine, albeit perhaps slower.

So the reason the behavior is different is that you're calling two completely different methods, which do different things, but happen to have the same name. No, it's not a bug.

like image 158
Craig Stuntz Avatar answered Feb 05 '23 18:02

Craig Stuntz