For a simple repository
public interface ISimpleRepository<T>
{
IApplicationState AppState { get; set; }
void Add(T instance);
void Delete(T instance);
void Delete(Guid rowGuid);
IQueryable<T> GetAll();
T Load(Guid rowGuid);
void SaveChanges();
void Update(T instance);
}
my implementation of the Load()
method for specific repository for class Product
might look like this:
public Product Load(Guid rowid)
{
return (from c in _ctx.Products where c.id == rowid select c).FirstOrDefault();
}
Now this is assumed when my repository implementation class looks like this:
public class EntityFrameworkProductsProvider : IRepository<Product> ...
What if I had like dozens or hundreds of this small and simple entities that would all use the same behaviour when doing CRUDs (use the same implementation of methods)? I certainly don't want to go and create a class to implement IRepository for each one of them..
I want something like this:
public class EntityFrameworkDefaultProvider<T> : IRepository<T> ...
but I don't know how to implement the LINQ Select expression then because of course I can't write from e in _ctx.T where e...
or do I?
I haven't run into this scenario yet because so far I only had very specific entities with custom repository implementation.
Instead of writing _ctx.Products
, you can write _ctx.Set<T>
. That takes care of half of the problem (you need to add a generic constraint where T: class
to your repository)
Then, if rowid is the object's key, you can use _ctx.Set<T>.Find(rowid)
instead of a LINQ query to retrieve by Id.
Alternatively, you can create a base interface IHaveId
(or a BaseEntity
class, whatever you like) which has the Id
property, and then add that as an generic constraint on T, so you can use it in your queries.
Because you tagged your question with entity-framework and entity-framework-4 I assume you are using ObjectContext API. ObjectContext
offers method CreateObjectSet<T>
which is equivalent of Set<T>
on DbContext
.
This question is actually duplicate of either:
- Generic GetById with DbContext
- Generic GetById with ObjectContext
If you're using EF 4.1, see the sample generic repository here:
http://www.asp.net/entity-framework/tutorials/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application
I know that this is possible in EF4.1 with the DbContext API, where you have a "Set" method on the context that gets you the entity set corresponding to the type T. this way, you could have your repository like this:
public class EntityFrameworkDefaultProvider<T> : IRepository<T> where T:class
{
public T Load(Guid rowId)
{
return _context.Set<T>().Find(rowId);
}
}
one more remark: I think you could use this syntax :
return _ctx.Products.FirstOrDefault(c=>c.id == rowid);
to get the entity you want instead of using the (from... in...). it's clearer (in my opinion) :)
Hope this helps