Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NHibernate query runs only once, then throws InvalidCastException

Tags:

I have a simple query like below:

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();

It successfully runs once, but when executed in the second time(or third, fourth and so son) it throws an invalid cast exception like:

Fatal Error:System.InvalidCastException: Cannot convert type 'System.Linq.EnumerableQuery`1[<>f__AnonymousType0`3[System.Int64,System.DateTime,Team]]' to 'System.Collections.Generic.IEnumerable`1[<>f__AnonymousType0`3[System.Int64,System.DateTime,Team]]'. in NHibernate.Linq.DefaultQueryProvider.Execute[TResult](Expression expression)

Rest of the stack trace supressed for bravety.

The query is always executed in database before the error. It returns no records, but its is ok. If I rebuild the solution and run again, the query is executed in first time again, and then start throwing the exception each other time I run it. Other queries runs everytime w/o any problems. I have no idea of what causes the error.

Its important to say that this code is running in an CSharpCodeProvider environment, but I don't know if it can make a difference.

UPDATE

It happens even with the most simple form of the query:

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

It runs ok for the first time only. But if I change the annon object from { x.Id } to { x.TeamId }, for example, it runs ok in the first time, then the exceptions occurs again.

UPDATE 2

I just realize that if I add the following property to the annon object, the query works everytime:

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

So, a cache issue maybe?

UPDATE 3

I updated the NHibernate from 3.3 to 4.0.0.4 and it solves almost all problems except by one query:

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();

Error message:

GenericADOException: The value "{ HoliDayCities = System.Collections.Generic.List`1[System.Int64], HoliDayStates = System.Collections.Generic.List`1[System.Int64], Date = 01/02/2015 00:00:00 }" is not "<>f__AnonymousType1`3[System.Collections.Generic.List`1[System.Int64],System.Collections.Generic.List`1[System.Int64],System.DateTime]" and cannot be used on this collection. Parameter name: value

If I add the Rnd() function on Select scope as I mentioned before, it works fine. The problem occurres only with anonymous object.

like image 327
DontVoteMeDown Avatar asked Jan 29 '16 16:01

DontVoteMeDown


1 Answers

It looks like it is an issue with manipulating anonymous types and NHibernate. I would highly suggest returning a simple resultset, materializing the resultset with ToList(), and then doing projections on that resultset.

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

var projectedTeam = employeeTeam.Select(x => new {x.Id});
like image 194
gnicholas Avatar answered Jan 06 '23 16:01

gnicholas