簡體   English   中英

在EF的通用參數上使用Equals時出錯

[英]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>.Enumeratorstruct 在這種情況下,頭腦會困惑於“相等”的含義。

我的觀點是,編譯器在編譯時無法知道除了使用object.Equals之外該如何做。

我不知道為什么您無論如何都要限制鍵類型為struct 我見過的最常見的ID類型是intstring 通過使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM