【问题标题】:Linq expression does not allow Generic Property TypeLinq 表达式不允许通用属性类型
【发布时间】: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&lt;TEntity&gt;.

但是当我使用 Linq 查找特定实体时,它会在我写这篇文章的开头时引发异常。

注意:我要查找的实体具有 int 类型的 Id,因此它是原始类型...

注 1:我不能将 '==' 运算符与泛型类型 TKey 一起使用。我得到编译错误。

注2:我也试过这个Where(e=&gt;e.Id.GetHashCode()==id.GetHashCode())。这会引发另一个错误(运行时)。

LINQ to Entities 无法识别方法“Int32 GetHashCode()”方法,并且该方法无法转换为存储表达式。

【问题讨论】:

  • 我通过向通用存储库添加 Where 方法实现了这一点,该方法允许使用谓词参数。然后我将谓词向下推为return GetAll().Where(predicate).FirstOrDefault();
  • 顺便说一句,为什么IComparable&lt;T&gt;IEquatable&lt;T&gt;Id 相等不是更好吗?
  • e.Id == id 会出现什么编译错误?
  • 另一方面,当 EF 已有 Find 方法时,为什么还要使用 IQueryable&lt;T&gt;?我的意思是,存储库的 GetById 应该调用 EF 的 Find 对应...
  • 请记住,LINQ-to-entity 将查询转换为 SQL 命令,而在 SQL 中没有像 CompareToGetHashCode 这样的东西。并非每个有效的 C# 表达式都会转换为 SQL。

标签: c# .net linq generics


【解决方案1】:

我没有尝试解决最初的问题,因为其他一些用户已经评论说并非所有有效的表达式都可以在后台转换为 SQL,我将尝试给您一些建议...

总结:

  • 您希望Id 实现IEquatable&lt;TId&gt;,而不是IComparable&lt;TId&gt;。因此,您将能够编写如下类型的等式:id.Equals(id2)。 BTW EF 也无法处理IEquatable&lt;T&gt;.Equals(请参阅Is it possible to use IComparable to compare entities in Entity Framework?)。无论如何,你不会再走这条路了,但建议仍然有效,你想要IEquatable&lt;T&gt;,而不是比较。 查看下一点了解原因
  • 您不希望您的存储库上的GetAll 方法稍后通过Id 查找实体。对于这个确切的用例,实体框架已经有IDbSet&lt;T&gt;.Find method

另外,我鼓励您阅读我在 2011 年(很久以前)针对存储库中的 GetAll 撰写的一些答案:Repository design pattern。此外,我还记录了存储库模式 here,我在其中也针对 GetAll 进行了解释。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-09-30
    • 2019-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-17
    • 1970-01-01
    相关资源
    最近更新 更多