2010-08-07 55 views
3

所以我試圖創建一個通過ID方法爲基礎存儲庫類的通用選擇。爲了達到這個目的,我使用了POCO的EF4。我創建了一個名爲Id的getter接口,併成功修改了T4模板,以便在返回PK的所有實體中都有一個通用的Id屬性。在EF4中通過ID選擇通用存儲庫

問題出在我使用查詢時。我採取這樣的:

public virtual T GetByID(int id) 
{ 
    return Database.ObjectSet<T>().SingleOrDefault(entity => entity.Id == id); 
} 

而且即使在對象集返回的所有實體具有Id屬性與他們當前的主鍵值設置,我發現了一個奇怪的錯誤:

The specified type member 'Id' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.

我錯過了什麼嗎?

回答

3

如果只有泛型Id(如你所說)「返回PK」但實際上並沒有映射到PK本身,那麼EF就無法將它轉換爲SQL查詢。

過去我用過的一種模式:如果所有的實體都有一個名爲Id的int PK,那麼你可以讓它們都從某個基類繼承而來,其中的Id屬性被定義(映射到),然後請在您的通用方法中添加where子句:

public virtual T GetByID(int id) where T : EntityBaseClass 

僅供參考,我也將此用於具有使用泛型的不同類型PK的實體。

+0

Id的吸氣礦庫返回的PK是映射實體的財產。另外,ObjectSet ()方法具有以下簽名。 public virtual IObjectSet ObjectSet ()其中T:class,IEntity。 IEntity是映射我所有實體PK的接口。 – 2010-08-08 06:11:46

+1

正如我所提到的,如果ID是返回PK的屬性,但未映射,EF應如何知道如何生成查詢?就EF而言,這不是映射到DB,也不能被查詢!您需要針對映射的屬性本身進行查詢,該解決方案是使用基類。另外,如果你映射實際的ID屬性(而不是僅僅從getter中返回PK),那也可以。 – hackerhasid 2010-08-08 12:26:17

+0

感謝您的評論和答覆。 – 2010-08-08 22:22:22

1

我不知道。我認爲

public virtual T GetByID(int id) 

這是一個壞主意,因爲它是一個硬編碼。 如果我有一個guid鍵的實體會怎麼樣?

爲STE實體

public interface IRepository<TE, TK> 
    where TE : class, IEntityId<TK>, new() 
    where TK : struct 
{ 
    IQueryable<TE> Query(); 
    IQueryable<TE> Query(Expression<Func<TE, Object>> includeExpression); 
    IQueryable<TE> Query(IEnumerable<Expression<Func<TE, Object>>> includeExpressions); 

    TE GetById(Expression<Func<TE, Boolean>> predicate); 
    void Create(TE entity); 
    void Update(TE entity); 
    void Delete(TE entity); 
} 

    public interface IEntityId<out TK> where TK : struct 
{ 
    TK Id { get; } 
    Int32 OwnerCode { get; } 
} 
+2

如果您要提供一個表達式,那麼我在IEntityId接口中看不到該值 - 我錯過了什麼? – 2011-02-17 12:13:03