奇怪的linq到nhibernate问题,来自“System.Int32”的无效强制转换
在以下代码中调用Get可以正常工作:奇怪的linq到nhibernate问题,来自“System.Int32”的无效强制转换,nhibernate,linq-to-nhibernate,Nhibernate,Linq To Nhibernate,在以下代码中调用Get可以正常工作: public class ContractService : IContractService { private readonly IRepository<Contract> repository; public ContractService(IRepository<Contract> repository) { this.repository = repository; }
public class ContractService : IContractService
{
private readonly IRepository<Contract> repository;
public ContractService(IRepository<Contract> repository)
{
this.repository = repository;
}
public Contract Get(int contractId)
{
return repository.Query().Where(x => x.Id == contractId).FirstOrDefault();
}
有人知道为什么吗
编辑:以下是不同表达式的外观:
在泛型版本top one中,它似乎出于某种原因试图转换x,这一定是因为泛型:s
{value(NHibernate.Linq.Query`1[Contract]).Where(x => (Convert(x).Id = value(CRUDService`1+<>c__DisplayClass0[Contract]).Id)).FirstOrDefault()}
{value(NHibernate.Linq.Query`1[Contract]).Where(x => (x.Id = value(ContractService+<>c__DisplayClass2).Id)).FirstOrDefault()}
第三次编辑:似乎是Convertx导致AssociationVisitor无法正确访问表达式树并转换Convertx.Id
第四次编辑:我们开始了,有些人已经发现了错误
谢谢
Andrew我以前遇到过这个问题,它通常归结为您正在读取的数据库表中的字段格式不兼容。就像布尔运算一样,它不会转换成整数
检查表中的字段类型,确保它们兼容。也许你的Id列是一个BIGINT 我认为问题在于Linq/NHibernate试图将ienty.Id映射到表列,而不是tenty.Id。我在LinqToSql存储库实现中遇到了这个问题。解决方法是使用这样一个表达式:
private static Expression<Func<TEntity, bool>> GetFindExpression(string propertyName, object value)
{
ParameterExpression parameterExpression = Expression.Parameter(typeof (TEntity), "id");
MemberExpression propertyExpression = Expression.Property(parameterExpression, propertyName);
Expression bodyExpression = Expression.Equal(propertyExpression, Expression.Constant(value));
return Expression.Lambda<Func<TEntity, bool>>(bodyExpression, parameterExpression);
}
更新:
如果你不想处理表达式,它们可能会很棘手!,您可以使用动态LINQ库,如Scott Guthrie所述:
这会将Getid更改为:
public TEntity Get(int id)
{
var entities = Query.Where(GetFindExpression("Id", id));
return entities.FirstOrDefault();
}
public TEntity Get(int id)
{
var entities = Query.Where("Id = @0", id);
return entities.FirstOrDefault();
}
我也有同样的问题: 以下方法不起作用
public override T Load(int id)
{
return (from t in _sessionFactory.Session.Linq<T>()
where t.ID == id
select t).SingleOrDefault();
}
下面是一个例子
public override Product Load(int id)
{
return (from t in _sessionFactory.Session.Linq<Product>()
where t.ID == id
select t).SingleOrDefault();
}
该错误已报告,但尚未修复: 我发布了一个简单的测试用例来复制它
希望它能尽快得到解决 听起来确实很奇怪。您是否有正在执行的SQL的日志?堆栈跟踪的其余部分是什么样子的?似乎没有运行SQL,看起来Linq在接近DB之前就失败了。我刚刚下载了调试的源代码,我也遇到了这个问题!Linq to NHibernate目前正在重写,我一直在处理这个问题,直到它发布。我同意这可能会导致无效的强制转换异常,但这不是这里发生的事情。阅读jira的代码和错误报告。这是由generics引起的一个bug我认为问题在于Linq/NHibernate试图将IEntity.Id映射到表列,而不是TEntity.Id。我完全同意。我喜欢转换lambda的想法,我将尝试制作一个通用版本,它将处理所有转换。。。我注意到你添加了一个测试用例,做得不错。希望他们能尽快解决这个问题!
public TEntity Get(int id)
{
var entities = Query.Where("Id = @0", id);
return entities.FirstOrDefault();
}
public override T Load(int id)
{
return (from t in _sessionFactory.Session.Linq<T>()
where t.ID == id
select t).SingleOrDefault();
}
public override Product Load(int id)
{
return (from t in _sessionFactory.Session.Linq<Product>()
where t.ID == id
select t).SingleOrDefault();
}