[英]Getting errors when using Equals on generic parameters with EF
我有以下两个通用类:
public abstract class Entity<T> : IEntity<T>, IAuditableEntity,ISoftDeletable where T : struct
{
public T Id { get; set; }
public DateTime CreatedDate { get; set; }
public string CreatedBy { get; set; }
public DateTime UpdatedDate { get; set; }
public string UpdatedBy { get; set; }
public bool Deleted { get; set; }
}
public abstract class Repository<TEntity,TKey> : IRepository<TEntity, TKey> where TEntity :Entity<TKey> where TKey : struct
{
protected DbContext Context;
protected readonly IDbSet<TEntity> Set;
protected Repository(DbContext context)
{
Context = context;
Set = Context.Set<TEntity>();
}
public TEntity Get(TKey key)
{
var output = Set.FirstOrDefault(o => o.Id.Equals(key));
return output ;
}
}
我的问题是Get方法。 我不断收到这个错误
无法创建类型为'System.Object'的常量值。 在这种情况下,仅支持原始类型或枚举类型。”
我试图使用==但它不会编译并说
不能将==应用于操作数TKey和TKey
为什么这不起作用? 我的TKey应该是原始数据类型,不是TKey:struct正确的限制器吗?
为什么在有Equals(int)的情况下,编译器为什么使用Equals(object)?
==
比较失败,因为该运算符只能用于预定义的值类型或引用类型,而您的TKey
都不可用。
您在评论中说TKey
是一个int
。 在您的情况下可能是对的 ,但是您的类的用户可以定义Entity<List<string>.Enumerator>
因为List<T>.Enumerator
是struct
。 在这种情况下,头脑会困惑于“相等”的含义。
我的观点是,编译器在编译时无法知道除了使用object.Equals
之外该如何做。
我不知道为什么您无论如何都要限制键类型为struct
。 我见过的最常见的ID类型是int
和string
。 通过使用struct
您已经排除了string
...
您是否真的需要灵活性来支持非整数键? 如果没有,您的课程可能会简单得多。
更新 :您可以限制TKey
使其实现IComparable
,因为所有数字类型都可以实现。 然后,您可以在Get
方法的实现中使用CompareTo
。
但是,由于传递给FirstOrDefault
的lambda实际上将在数据库端执行,因此我不确定会发生什么,即EF是否能够将其正确转换为SQL表达式。
public abstract class Entity<T> : IEntity<T>, IAuditableEntity,ISoftDeletable where T : struct, IComparable
public abstract class Repository<TEntity,TKey> : IRepository<TEntity, TKey> where TEntity :Entity<TKey> where TKey : struct, IComparable
您可以简单地使用IDbSet.Find
方法,该方法采用一个或多个object
类型的键值。
public TEntity Get(TKey key)
{
return Set.Find(key);
}
这样做还有一个好处,就是如果该实体已经存在于DbContext
的本地缓存中,则效率更高(因为它避免了不必要的数据库访问)。
但是,我怀疑您将要做的不仅仅是检索单个项目,因此以后您可能会遇到相同的问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.