我有一个简单的查询,如下所示:
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:无法转换类型&#39; System.Linq.EnumerableQuery`1 [&lt;&gt; f__AnonymousType0`3 [System.Int64,System.DateTime,Team]]&#39;到&#39; System.Collections.Generic.IEnumerable`1 [&lt;&gt; f__AnonymousType0`3 [System.Int64,System.DateTime,Team]]&#39;。在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:值&#34; {HoliDayCities = System.Collections.Generic.List`1 [System.Int64],HoliDayStates = System.Collections.Generic.List`1 [System.Int64],Date = 01/02/2015 00:00:00}&#34;不是 &#34;&LT;&GT; f__AnonymousType1`3 [System.Collections.Generic.List`1 [System.Int64],System.Collections.Generic.List`1 [System.Int64]的System.DateTime]&#34; 并且不能用于此集合。参数名称:值
如果我在Rnd()
范围内添加Select
函数,如前所述,它可以正常工作。问题只发生在匿名对象上。
答案 0 :(得分: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});
答案 1 :(得分:-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
});