I have the following methods on a Entity Framework 6 generic Repository:
public void Add<T>(T entity) where T : class {
_context.Set<T>().Add(entity);
} // Add
public void Add<T>(Expression<Func<T, Boolean>> criteria) where T : class {
_context.Set<T>().AddRange(_context.Set<T>().Where(criteria));
} // Add
public IQueryable<T> Find<T>(Expression<Func<T, Boolean>> criteria) where T : class {
return _context.Set<T>().Where(criteria);
} // Find
How can I make these methods async?
Thank You,
Miguel
I really don't think you should force your repository to be async. What you should do instead is to make async your business logic, that would eventually reference your repositories and access them as needed. Your data access shouldn't know anything about the way it will be used somewhere else.
Related
Should I use these 5 methods, only? Or should my Repository show all of the sql methods I am requiring. Perhaps I misunderstand the examples. Should I FindByID and and FindAll? For example, if I have 5 dropdowns. I have 5 methods, or I may have one method, 5 queries, and return 1 table and bind to 0-4 tables.
What I have tried, is several lessons online and several articles and I still feel like the examples are over simplified. Or, I am writing way too many methods to query the db.
BTW, I am moving from linear development to repositories and factories. so, my transition is predicated on understanding this and then I would move to EF, and MVC.
public interface IRepository<T> where T: IEntity
{
void Insert(Student student);
void Delete(Student student);
void Update(Student student);
Student GetById(Student RollNo);
IQueryable<Student> FetchAll();
}
For simple entities and aggregates having a standard set of CRUD operations on your repository makes a lot of sense. However, for less standard aggregates and complicated operations it doesn't make sense to implement these common operations.
For example: Suppose before you want to add your student to the database, you need to make some complicated validation over that student and hide those details over the client.
Preferably, I like to use the DBContext directly. It gives me more free space to do whatever i need without thinking too much for adding that method to the interface, and go to implement it.
Anyway if you want to use Repository pattern. I recommend to use the generic one such as the following:
public class Repository<TEntity> : IRepository<TEntity> where TEntity : class, IEntity
{
private readonly CrudContext _context;
private readonly DbSet<TEntity> _dbSet;
public Repository(CrudContext context)
{
this._context = context;
this._dbSet = context.Set<TEntity>();
}
public IEnumerable<TEntity> List()
{
return _dbSet.ToList();
}
public TEntity GetById(int id)
{
return _dbSet.Find(id);
}
public void Insert(TEntity entity)
{
_dbSet.Add(entity);
_context.SaveChanges();
}
public void Update(TEntity entity)
{
_dbSet.Attach(entity);
_context.Entry(entity).State = EntityState.Modified;
_context.SaveChanges();
}
public void Delete(int id)
{
var entityToDelete = _dbSet.Find(id);
_dbSet.Remove(entityToDelete);
_context.SaveChanges();
}
}
If it comes to my preference, Either I would use the dbcontext directly inside the dependent class or I would create an Interface called IEntityInserter and for each Record type or Model that has too much logic of inserting, I would create an implementation called
StudentBasedEntityInserter : IEntityInserter<Student> {
public void Insert(Student #student){}
}
and inject that IEntityInserter in any dependent class.
Finally, There is not right answers int that heated topic, some people would agree with my approach, others won't. Hope that it helps.
I am trying to implement a generic repository pattern. I found this site which I think its well explained.
http://www.tugberkugurlu.com/archive/generic-repository-pattern-entity-framework-asp-net-mvc-and-unit-testing-triangle
My purpose is to save the developers some time and keystrokes and I know this will help me.
So I have 2 questions:
1. Is this a good approach or not, will I have some problems in the future?
2. How can I combine it with Unitofwork pattern?, I cant create an instance of the abstract class of course, so the following code its invalid.
public class UnitOfWork : IDisposable
{
#region Private fields
private readonly MyCompanyContext _context = new MyCompanyContext();
private GenericRepository<MyCompanyContext, Task> _taskRepository;
public GenericRepository<MyCompanyContext, Task> TaskRepository
{
get
{
return _taskRepository ??
(_taskRepository = new GenericRepository<MyCompanyContext, Task>());
}
}
namespace MyCompany.DAL.Repository
{
public interface IGenericRepository<T> where T : class
{
IQueryable<T> GetAll();
IQueryable<T> FindBy(Expression<Func<T, bool>> predicate);
void Add(T entity);
void Delete(T entity);
void Edit(T entity);
void Save();
}
public abstract class GenericRepository<C, T> :
IGenericRepository<T>
where T : class
where C : DbContext, new()
{
private C _entities = new C();
public C Context
{
get { return _entities; }
set { _entities = value; }
}
public virtual IQueryable<T> GetAll()
{
IQueryable<T> query = _entities.Set<T>();
return query;
}
public IQueryable<T> FindBy(System.Linq.Expressions.Expression<Func<T, bool>> predicate)
{
IQueryable<T> query = _entities.Set<T>().Where(predicate);
return query;
}
public virtual void Add(T entity)
{
_entities.Set<T>().Add(entity);
}
public virtual void Delete(T entity)
{
_entities.Set<T>().Remove(entity);
}
public virtual void Edit(T entity)
{
_entities.Entry(entity).State = System.Data.EntityState.Modified;
}
public virtual void Save()
{
_entities.SaveChanges();
}
}
}
There are several opinions regarding repositories, but after trying various repository implementations in production for couple years myself, I agree with Ayende's opinion, that repository, especially generic, is redundant abstraction layer.
I liked very much this course:
http://www.pluralsight-training.net/microsoft/Courses/TableOfContents/linq-architecture
It walked through most possible solutions and explained goods and bads.
What we're using right now is very thin abstraction over datacontext, just to overcome Linq2Sql testability issues, which are irrelevant in most cases when using EF.
With a lot of effort you might get that working, but I wonder if the effort is really worth it? I've seen implementations like this before, and they really struggle when attempting to manage many-to-many relationships (have a think about how you'd manage that in your scenario).
You are using Entity Framework, an ORM right? ORMs like Entity Framework and nHibernate are designed to abstract the database implementation from application code, so what is the purpose of adding yet another abstraction above it to manage entities at such a granular level? If it's a question of testing, then you can use a mocking framework to mock the context, thus removing the need for an actual database during testing. If however, for architectural or security reasons you are seeking to remove interactions with a db context from your app code, I'd recommend for pragmatism using an implementation of the command pattern over the top of the entity framework. I've needed to do this on a larger scale enterprise (banking) application where for security reasons (rightly or wrongly) we were absolutely not allowed to have a db connection in our application code.
I have the following fake repository that I use for unit testing. How would I implement the Attach(T entity) method in this repository?
(In my real repository, the Attach(T entity) method is used to attach an object to my Entity Framework 4 data context).
public class FakeRepository<T> : IRepository<T> where T : class, new()
{
private static List<T> entities = new List<T>();
public IQueryable<T> Entities
{
get { return entities.AsQueryable(); }
}
public T New()
{
return new T();
}
public void Create(T entity)
{
entities.Add(entity);
}
public void Delete(T entity)
{
entities.Remove(entity);
}
public void Attach(T entity)
{
//How to implement Attach???
}
public void Save()
{
//Do nothing
}
public void Dispose()
{
return;
}
}
To answer this, you have to ask yourself "what is the purpose of "Attach?" You probably know that the point is to tell the repository "this object is persisted in the database but you aren't currently tracking it; I have made updates to it and I want you to commit them when I tell you to submit your changes."
Thus, to test that Attach is working properly, you should maintain a collection of attached objects and add an entity to this collection when it is passed a parameter to Attach.
So, the simplest implementation would be
entities.Add(entity);
but you could consider something more fine-grained. Note that you need to expose a method that lets you assert that the entity was successfully attached (in EF4 you can use ObjectStateManager.TryGetObjectStateEntry).
get rid of the static word on the entities member. Now just do
enitities.Add(entity)
I'm currently developing a medium sized application, which will access 2 or more SQL databases, on different sites etc...
I am considering using something similar to this:
http://mikehadlow.blogspot.com/2008/03/using-irepository-pattern-with-linq-to.html
However, I want to use fluent nHibernate, in place of Linq-to-SQL (and of course nHibernate.Linq)
Is this viable?
How would I go about configuring this?
Where would my mapping definitions go etc...?
This application will eventually have many facets - from a WebUI, WCF Library and Windows applications / services.
Also, for example on a "product" table, would I create a "ProductManager" class, that has methods like:
GetProduct, GetAllProducts etc...
Any pointers are greatly received.
In my opinion (and in some other peoples opinion as well), a repository should be an interface that hides data access in an interface that mimics a collection interface. That's why a repository should be an IQueryable and IEnumerable.
public interface IRepository<T> : IQueryable<T>
{
void Add(T entity);
T Get(Guid id);
void Remove(T entity);
}
public class Repository<T> : IQueryable<T>
{
private readonly ISession session;
public Repository(ISession session)
{
session = session;
}
public Type ElementType
{
get { return session.Query<T>().ElementType; }
}
public Expression Expression
{
get { return session.Query<T>().Expression; }
}
public IQueryProvider Provider
{
get { return session.Query<T>().Provider; }
}
public void Add(T entity)
{
session.Save(entity);
}
public T Get(Guid id)
{
return session.Get<T>(id);
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
public IEnumerator<T> GetEnumerator()
{
return session.Query<T>().GetEnumerator();
}
public void Remove(T entity)
{
session.Delete(entity);
}
}
I do not implement a SubmitChanges like method in the repository itself, because I want to submit the changes of several repositories used by one action of the user at once. I hide the transaction management in a unit of work interface:
public interface IUnitOfWork : IDisposable
{
void Commit();
void RollBack();
}
I use the session of an NHibernate specific unit of work implementation as session for the repositories:
public interface INHiberanteUnitOfWork : IUnitOfWork
{
ISession Session { get; }
}
In a real application, I use a more complicated repository interface with methods for things like pagination, eager loading, specification pattern, access to the other ways of querying used by NHiberante instead of just linq. The linq implementation in the NHibernate trunk works good enough for most of the queries I need to do.
Here are my thoughts on generic repositories:
Advantage of creating a generic repository vs. specific repository for each object?
I have successfully used that pattern with NHibernate, and haven't found any real shortcomings.
The gist is that truly generic repositories are a bit of a red herring, but the same benefits can be realized by thinking about the problem slightly differently.
Hope that helps.
I am trying to create a generic base repository for my Linq2Sql entities. I'd like to implement a generic FindAll() method like so.
class BaseRepository<T> : IBaseRepository<T>
{
private readonly FooDataContext _ctx = new FooDataContext();
public IQueryable<T> FindAll()
{
return _ctx.T;
}
public void Add(T entity)
{
_ctx.T.InsertOnSubmit(entity);
}
public void Save()
{
_ctx.SubmitChanges();
}
}
Is there any way to do this without having to use reflection and create slowdown that would make it virtually worthless?
DataContext has what you need in it already.
public IQueryable<T> FindAll()
{
return _ctx.GetTable<T>();
}
public void Add(T entity)
{
_ctx.GetTable<T>().InsertOnSubmit(entity);
}
If you use an in-memory storage system to cache the reflected attributes of a specific type after the first use, you may not have a "virtually worthless" situation at all. In fact, without testing it, you don't really know that the reflection solution would be a problem, do you? (Much of .NET uses reflection and people don't see slowdown in those scenarios. Serialization is one of them.)
This should work:
public IQueryable<T> FindAll()
{
return _ctx.GetTable<T>();
}