2012-12-19 18 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