#entity-framework #linq-to-entities
#entity-framework #linq-to-entities
Вопрос:
Чтобы выбрать все Scheduling
, которые активны, у меня есть следующий код:
var allSchedulesOnALine = CurrentUser.Lines.SelectMany(o => o.Scheduling).Where(o => o.Active);
var allSchedulesUnscheduled = Entities.SchedulingSet
.Where(o => o.Line == null amp;amp; o.Site.Id == CurrentUser.Site.Id amp;amp;
o.Factory == CurrentUser.Factory amp;amp; o.Active);
IEnumerable<Scheduling> allSchedules = allSchedulesUnscheduled.Union(allSchedulesOnALine);
foreach(Scheduling schedule in allSchedules.OrderBy(o => o.Ordering))
{
//Do Stuff
}
( Factory
является int
)
Когда я запускаю этот код, я получаю эту загадочную ошибку в foreach
строке:
Не удается создать постоянное значение типа ‘System.Коллекции.Общий.IEnumerable`1’. В этом контексте поддерживаются только примитивные типы (‘такие как Int32, String и Guid’).
Как ни странно, я могу перечислять оба allSchedulesOnALine
и allSchedulesUnscheduled
по отдельности. Еще более странно, если я изменю порядок объединения:
IEnumerable<Scheduling> allSchedules = allSchedulesOnALine.Union(allSchedulesUnscheduled);
Это работает нормально!
У кого-нибудь есть идеи, почему это могло произойти? Я упускаю что-то важное, или это ошибка?
Я должен упомянуть, что я использую Entity Framework 3.5. EF4 в настоящее время для нас не подходит — это вне моего контроля :
Комментарии:
1. Я полагаю, что сообщение об ошибке указывает на то, что EF не может перевести ваш оператор union в SQL, но я не уверен, почему. Возможно ли, что
CurrentUser.Lines.SelectMany(o => o.Scheduling).Where(o => o.Active)
не используется отложенное выполнение? В таком случае это может объяснить, почему вы можете использовать его в одном направлении, но не в другом — одно выполняется в памяти, другое пытается полностью выполняться в SQL. Мысли?
Ответ №1:
Вы вызываете два разных метода с вашим «переупорядочением».
Вы не показываете типы allSchedulesOnALine
или allSchedulesUnscheduled
, но я уверен, что allSchedulesOnALine
имеет тип IEnumerable<Schedule>
и allSchedulesUnscheduled
имеет тип IQueryable<Schedule>
.
Итак, когда вы вызываете Queryable.Объединение, вы просите EF перевести выражение в SQL. Но передаваемый вами аргумент имеет тип IEnumerable<Schedule>
, и он не может преобразовать это в запрос.
С другой стороны, когда вы вызываете Enumerable.Объединение, вы просите LINQ to Objects выполнить все это в памяти, что работает нормально, хотя, возможно, медленнее.
Итак, причина, по которой поведение отличается, заключается в том, что вы вызываете два совершенно разных метода, которые выполняют разные действия, но случайно имеют одинаковое имя. Нет, это не ошибка.
Комментарии:
1. Это, должно быть, десятый раз, когда вы помогаете мне с проблемой EF здесь, включая, я думаю, эту точную проблему раньше (тьфу). Еще раз спасибо, Крейг!