【发布时间】:2017-02-21 19:23:56
【问题描述】:
错误:无法创建“System.Object”类型的常量值。此上下文仅支持原始类型或枚举类型。
好吧,这就是交易, 我有一个通用基础实体,如下所示:
public abstract class Entity<Tkey> : IEntity<Tkey>
where Tkey:IComparable
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public abstract Tkey Id { get; set;}
}
我更喜欢这个,因为你知道,有些表的 Identity 列类型是 Guid,有些是 int,有些是 long。
所以,在我的通用存储库中,我有一些类似这样的方法:
public class FRepository<TEntity,Tkey>:IDisposable where TEntity : Entity<Tkey>, new()
where Tkey:IComparable
{
public TEntity Find(Tkey id)
{
return this.GetAll().Where(e=> e.Id.CompareTo(id)==0).FirstOrDefault();
}
}
GetAll() 方法返回IQueryable<TEntity>.
但是当我使用 Linq 查找特定实体时,它会在我写这篇文章的开头时引发异常。
注意:我要查找的实体具有 int 类型的 Id,因此它是原始类型...
注 1:我不能将 '==' 运算符与泛型类型 TKey 一起使用。我得到编译错误。
注2:我也试过这个Where(e=>e.Id.GetHashCode()==id.GetHashCode())。这会引发另一个错误(运行时)。
LINQ to Entities 无法识别方法“Int32 GetHashCode()”方法,并且该方法无法转换为存储表达式。
【问题讨论】:
-
我通过向通用存储库添加 Where 方法实现了这一点,该方法允许使用谓词参数。然后我将谓词向下推为
return GetAll().Where(predicate).FirstOrDefault(); -
顺便说一句,为什么
IComparable<T>?IEquatable<T>与Id相等不是更好吗? -
e.Id == id会出现什么编译错误? -
另一方面,当 EF 已有
Find方法时,为什么还要使用IQueryable<T>?我的意思是,存储库的GetById应该调用 EF 的Find对应... -
请记住,LINQ-to-entity 将查询转换为 SQL 命令,而在 SQL 中没有像
CompareTo或GetHashCode这样的东西。并非每个有效的 C# 表达式都会转换为 SQL。