2012-12-19 35 views
7

讓我首先,我不確定這是否可能。我正在學習泛型,並在我的應用程序中有幾個存儲庫。我試圖製作一個採用泛型類型的接口並將其轉換爲所有存儲庫都可以繼承的接口。現在到我的問題。試圖在實體框架中使用泛型

public interface IRepository<T> 
{ 
    IEnumerable<T> FindAll(); 
    IEnumerable<T> FindById(int id); 
    IEnumerable<T> FindBy<A>(A type); 
} 

是否有可能使用通用以確定找什麼呢?

public IEnumerable<SomeClass> FindBy<A>(A type) 
{ 
    return _context.Set<SomeClass>().Where(x => x. == type); // I was hoping to do x.type and it would use the same variable to search. 
} 

爲了澄清一點點,我正在考慮是一個字符串,int或任何類型,我想搜索。我所希望的是,我可以說x.something在東西等於傳入的變量。

我可以使用

public IDbSet<TEntity> Set<TEntity>() where TEntity : class 
{ 
    return base.Set<TEntity>(); 
} 

任何建議設置的存儲庫,以我的DbContext?

回答

4

如果使用Expression<Func<T, bool>>,而不是A這樣的:

public interface IRepository<T> 
{ 
    ... // other methods 
    IEnumerable<T> FindBy(Expression<Func<T, bool>> predicate); 
} 

你可以使用linq查詢類型,並在調用存儲庫類的代碼中指定查詢。

public IEnumerable<SomeClass> FindBy(Expression<Func<SomeClass, bool>> predicate) 
{ 
    return _context.Set<SomeClass>().Where(predicate); 
} 

,並調用它是這樣的:

var results = repository.FindBy(x => x.Name == "Foo"); 

而且因爲它是一個通用的表情,你沒有實現它在每一個倉庫,你可以把它在通用基礎信息庫。

public IEnumerable<T> FindBy(Expression<Func<T, bool>> predicate) 
{ 
    return _context.Set<T>().Where(predicate); 
} 
+2

進行比較。我個人喜歡這種方法,但很多不這樣做。這意味着存儲庫的用戶需要知道哪些表達式是EF安全的,哪些不是,因爲這是一種泄漏抽象。 – stevenrcfox

0

我使用Interface和Abstract類的組合來實現這一點。

public class RepositoryEntityBase<T> : IRepositoryEntityBase<T>, IRepositoryEF<T> where T : BaseObject 
// 
public RepositoryEntityBase(DbContext context) 
    { 
     Context = context; 
//etc 

public interface IRepositoryEntityBase<T> : IRepositoryEvent where T : BaseObject //must be a model class we are exposing in a repository object 

{ 
    OperationStatus Add(T entity); 
    OperationStatus Remove(T entity); 
    OperationStatus Change(T entity); 
    //etc 

然後派生類可以在有幾個對象的具體方法或確實沒有什麼,只是工作

public class RepositoryModule : RepositoryEntityBase<Module>, IRepositoryModule{ 
    public RepositoryModule(DbContext context) : base(context, currentState) {} 
} 
//etc