Trying to use a generic with Entity Framework
Let me start with, I am not sure if this is possible. I am learning generics and I have several repositories in my app. I am trying to make an Interface that takes a generic type and converts it to something that all of the repositories can inherit from. Now on to my question.
public interface IRepository<T>
{
IEnumerable<T> FindAll();
IEnumerable<T> FindById(int id);
IEnumerable<T> FindBy<A>(A type);
}
Is it possible to use a generic to determine what to find by?
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.
}
To clarify a little better I was considering to be a string, int or whatever type I wanted to search for. What I am hoping for is I can say x.something where the something is equal to the variable passed in.
I can set any repository to my dbcontext using the
public IDbSet<TEntity> Set<TEntity>() where TEntity : class
{
return base.Set<TEntity>();
}
Any Suggestions?
If you use Expression<Func<T, bool>>
instead of A
like this:
public interface IRepository<T>
{
... // other methods
IEnumerable<T> FindBy(Expression<Func<T, bool>> predicate);
}
You can query the type using linq and specify the query in the code which calls the repository class.
public IEnumerable<SomeClass> FindBy(Expression<Func<SomeClass, bool>> predicate)
{
return _context.Set<SomeClass>().Where(predicate);
}
And call it like this:
var results = repository.FindBy(x => x.Name == "Foo");
And given that it's a generic expression, you don't have to implement it in each repository, you can have it in the generic base repository.
public IEnumerable<T> FindBy(Expression<Func<T, bool>> predicate)
{
return _context.Set<T>().Where(predicate);
}
I use a combination of Interface and Abstract classes to achieve exactly this.
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
then the derived classes can a have a few Object specific methods or indeed nothing and just work
public class RepositoryModule : RepositoryEntityBase<Module>, IRepositoryModule{
public RepositoryModule(DbContext context) : base(context, currentState) {}
}
//etc
链接地址: http://www.djcxy.com/p/67478.html
下一篇: 尝试在实体框架中使用泛型