Подтвердить что ты не робот

Запрос 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, команда]]". в NHibernate.Linq.DefaultQueryProvider.Execute [TResult] (выражение выражения)

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

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

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

UPDATE

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

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, как я упоминал ранее, она работает нормально. Проблема возникает только с анонимным объектом.

ОБНОВЛЕНИЕ 4

Я создал примерный проект для имитации проблемы. Это не совсем та же структура, но исключение довольно похоже. Именно на этом репо: https://github.com/felipeoriani/nh-bug

Не забудьте отключить строку 37, чтобы nhibernate создаст новые таблицы в базе данных.

4b9b3361

Ответ 1

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

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

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

Ответ 2

Я не думаю, что поставщик 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
                   });