[英]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.