调用以下代码中的Get工作正常:
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();
}
但是当我这样做时:
public class ContractService : CRUDService<Contract>, IContractService
{
public ContractService(IRepository<Contract> repository) : base(repository)
{
}
}
public class CRUDService<TEntity> : ICRUDService<TEntity> where TEntity : IEntity
{
protected readonly IRepository<TEntity> repository;
public CRUDService(IRepository<TEntity> repository)
{
this.repository = repository;
}
public TEntity Get(int id)
{
var entities = this.repository.Query().Where(s => s.Id == id);
return entities.FirstOrDefault();
}
当你迭代它时,get方法中的“entities”会引发异常:
Invalid cast from 'System.Int32' to 'TEntity' (where TEntity is the type name)
任何人都知道为什么?
编辑:这是不同表达式的样子:
在通用版本(顶部版本)中,似乎是出于某种原因试图转换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()}
(为清晰起见省略了名称空间)
第二次编辑:似乎是在尝试在IEntity和实例类型(TEntity)之间进行转换时
这是IEntity:
public interface IEntity
{
int Id { get; }
}
3rd Edit:似乎是Convert(x)导致AssociationVisitor没有正确访问表达式树并转换为“Convert(x).Id”
第四编辑:我们走了,有人已经找到了错误https://nhibernate.jira.com/browse/NHLQ-11!
由于
安德鲁
答案 0 :(得分:3)
我认为问题在于Linq / NHibernate试图将IEntity.Id映射到表列而不是TEntity.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);
}
所以这会将Get(id)改为:
public TEntity Get(int id)
{
var entities = Query.Where(GetFindExpression("Id", id));
return entities.FirstOrDefault();
}
<强>更新强>
如果您不想处理表达式(它们可能很棘手!),您可以使用Scott Guthrie所描述的Dynamic LINQ库: http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
这会将Get(id)更改为:
public TEntity Get(int id)
{
var entities = Query.Where("Id = @0", id);
return entities.FirstOrDefault();
}
答案 1 :(得分:1)
我过去遇到过这种情况,它通常归结为您正在阅读的数据库表中的字段不是兼容的格式。像布尔值不会转换为整数。
检查表格中的字段类型,确保它们兼容。也许你的Id专栏是BIGINT?
答案 2 :(得分:1)
我遇到同样的问题:(
以下不起作用。
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();
}
答案 3 :(得分:1)