Запрос NHibernate выполняется только один раз, затем генерирует исключение InvalidCastException

У меня есть простой запрос, как показано ниже:

var employeeTeam = Session.Query<EmployeeTeam>()
                       .Where(x => x.StartEffective <= competency.FinalDate && // competency.FinalDate is a DateTime
                                   employeesIds.Contains(x.EmployeeId)) // employeeIds is a List<long>
                       .OrderByDescending(x => x.StartEffective)
                       .Select(x => new
                       {
                           x.EmployeeId,
                           x.StartEffective,
                           x.Team
                       }).ToList();

Он успешно запускается один раз, но при выполнении во второй раз (или третий, четвертый и т. Д.) Он генерирует недопустимое исключение приведения типа:

Неустранимая ошибка:System.InvalidCastException: невозможно преобразовать тип 'System.Linq.EnumerableQuery`1[<>f__AnonymousType0`3[System.Int64,System.DateTime,Team]]' в 'System.Collections.Generic.IEnumerable`1[<>f__AnonymousType0`3[System.Int64,System.DateTime,Team]]. в NHibernate.Linq.DefaultQueryProvider.Execute[TResult](выражение выражения)

Остальная часть трассы стека подавлена ​​для смелых.

Запрос всегда выполняется в базе данных до ошибки. Он не возвращает никаких записей, но это нормально. Если я перестраиваю решение и запускаю снова, запрос выполняется снова в первый раз, а затем начинает выдавать исключение каждый раз, когда я его запускаю. Другие запросы выполняются каждый раз без каких-либо проблем. Я понятия не имею, что вызывает ошибку.

Важно сказать, что этот код выполняется в среде CSharpCodeProvider, но я не знаю, может ли это изменить ситуацию.

ОБНОВИТЬ

Это происходит даже с самой простой формой запроса:

var employeeTeam = Session.Query<EmployeeTeam>()
                       .Select(x => new
                       {
                           x.Id
                       }).ToList();

Он работает нормально только в первый раз. Но если я изменю объект annon с { x.Id } в { x.TeamId }Например, он запускается нормально в первый раз, затем исключения возникают снова.

ОБНОВЛЕНИЕ 2

Я просто понимаю, что если я добавлю следующее свойство к объекту annon, запрос будет работать каждый раз:

Rnd = (new Random().Next(1, 999))

Итак, проблема с кешем может быть?

ОБНОВЛЕНИЕ 3

Я обновил NHibernate от 3.3 в 4.0.0.4 и это решает почти все проблемы, кроме одного запроса:

var query = session.Query<Holiday>()
                   .Select(x => new {
                         HoliDayCities = x.City.Select(c => c.Id).ToList(),
                         HoliDayStates = x.State.Select(s => s.Id).ToList(),
    Date = new DateTime((int)(x.Year.HasValue ? x.Year : competencia.InitialDate.Year), (int)x.Month, (int)x.Day)
                   }).ToList();

Сообщение об ошибке:

GenericADOException: значение "{ HoliDayCities = System.Collections.Generic.List`1[System.Int64], HoliDayStates = System.Collections.Generic.List`1[System.Int64], Дата = 01/02/2015 00:00:00 }"не"<>f__AnonymousType1`3[System.Collections.Generic.List`1[System.Int64],System.Collections.Generic.List`1[System.Int64],System.DateTime]"и не может использоваться на этой коллекции. Имя параметра: значение

Если я добавлю Rnd() функция на Select Объем, как я уже говорил, работает нормально. Проблема возникает только с анонимным объектом.

2 ответа

Похоже, это проблема манипулирования анонимными типами и NHibernate. Я бы настоятельно рекомендовал вернуть простой набор результатов, материализовать набор результатов с помощью ToList(), а затем выполнить проекции для этого набора результатов.

var employeeTeam = Session.Query<EmployeeTeam>()
                          .Select(x => x)
                          .Where(x => x.Id != 0)
                          .ToList();

var projectedTeam = employeeTeam.Select(x => new {x.Id});

Я не думаю, что провайдер Nhib LINQ поддерживает эту проекцию как часть отложенного выполнения. Я думаю, что вы должны поставить свою проекцию после ToList()

var employeeTeam = Session.Query<EmployeeTeam>()
                   .Where(x => x.StartEffective <= competency.FinalDate &&    // competency.FinalDate is a DateTime
                               employeesIds.Contains(x.EmployeeId)) //  employeeIds is a List<long>
                   .OrderByDescending(x => x.StartEffective)
                   .ToList()
                   .Select(x => new
                   {
                       x.EmployeeId,
                       x.StartEffective,
                       x.Team
                   });
Другие вопросы по тегам