2010-05-31 32 views
3

我正在嘗試爲我目前正在開發的基於實體框架的項目編寫一個通用的最適合大多數存儲庫模式的模板類。在(重簡化)接口是:EntityFramework存儲庫模板 - 如何在模板類中編寫GetByID lambda?

internal interface IRepository<T> where T : class 
{ 
    T GetByID(int id); 
    IEnumerable<T> GetAll(); 
    IEnumerable<T> Query(Func<T, bool> filter); 
} 

GetByID被證明是殺手。在執行中:

public class Repository<T> : IRepository<T>,IUnitOfWork<T> where T : class 
{ 
    // etc... 
    public T GetByID(int id) 
    { 
    return this.ObjectSet.Single<T>(t=>t.ID == id); 
    } 

t => t.ID == id是我努力的特定位。是否有可能在沒有類特定信息可用的模板類中編寫像那樣的lambda函數?

+0

雖然我可以做類似||的事情public T GetSingle( filter)||如果可能的話,我真的更喜歡更簡單的GetByID,因爲每個存儲庫綁定的類將作爲一個堅實的規則擁有一個ID屬性。 – nathanchere 2010-05-31 06:47:05

+0

到目前爲止最接近的解決方案是返回查詢(函數(x)CType(x,Object).ID = ID)其中查詢是datacontext.Where(過濾器)的包裝。 – nathanchere 2010-06-02 03:49:54

回答

4

我VE定義的接口:

public interface IIdEntity 
{ 
    long Id { get; set; } 
} 


和改性產生我POCO類的T4模板,這樣所有的類必須實現公共接口的IIdentity接口。

像這樣:

using System.Diagnostics.CodeAnalysis; 
public partial class User : IIdEntity 
{ 
    public virtual long Id 
    { 
     get; 
     set; 
    } 

通過這種修改,我可以寫一個通用GetById(長ID),如:

public T GetById(long id) 
{ 
    return Single(e => e.Id == id); 
} 

的IRepository定義如下:

/// <summary> 
/// Abstract Base class which implements IDataRepository interface. 
/// </summary> 
/// <typeparam name="T">A POCO entity</typeparam> 
public abstract class DataRepository<T> : IDataRepository<T> 
    where T : class, IIdEntity 
{ 
+0

雖然這個問題的接受答案當時解決了我的問題,但我實際上使用了最近提到的方法,並且更喜歡它。 – nathanchere 2010-10-09 07:50:57

+0

更改爲接受此作爲答案,因爲它幾乎是我現在正在做的,這很好。使所有生成的類實現IEntity的T4 POCO生成器... – nathanchere 2010-11-07 12:00:08

2

您可以創建一個包含Id屬性的小接口,並將T限制爲實現它的類型。

編輯: 基礎上的評論,如果你接受這個事實,編譯器不會成爲幫助您確保ID屬性確實存在,你也許能夠做這樣的事情:

public class Repo<T> where T : class 
{ 
    private IEnumerable<T> All() 
    { 
     throw new NotImplementedException(); 
    } 

    private bool FilterOnId(dynamic input, int id) 
    { 
     return input.Id == id; 
    } 

    public T GetById(int id) 
    { 
     return this.All().Single(t => FilterOnId(t, id)); 
    } 
} 
+0

謝謝,+1。雖然它有效,但由於通用存儲庫模板的要點是簡單並且最大限度地減少了冗餘代碼,所以我希望有一個答案不需要使所有實體類都從某些GenericWithID類繼承。 – nathanchere 2010-06-01 23:26:11