My app is layered in 4 layers:
Core: where I put some general and interface classes.
Model: where my code-first classes, and other related to domain, such as entity configurations and repositories etc.
Vm: where the view models live. Referencing Model.
Desktop: where the desktop app lives. Referencing Vm.
I have installed Entity Framework into Model, ViewModel and Desktop.
My question is: is it enough to install it into Model only? Why to repeat again?
[Edit]
Here is my implementation of Repository and UnitOfWrok (
IRepository and Repository will be on Core):
public interface IRepository<TEntity> where TEntity : class
{
TEntity Get(int id);
IEnumerable<TEntity> GetAll();
IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate);
TEntity SingleOrDefault(Expression<Func<TEntity, bool>> predicate);
void Add(TEntity entity);
void AddRange(IEnumerable<TEntity> entities);
void Remove(TEntity entity);
void RemoveRange(IEnumerable<TEntity> entities);
}
public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
{
protected readonly DbContext Context;
public Repository(DbContext context)
{
Context = context;
}
public TEntity Get(int id)
{
return Context.Set<TEntity>().Find(id);
}
and so on...
}
Now, the new next interfaces and classed will be on Model
public interface ICountryRepository : IRepository<Country> {}
public class CountryRepository : Repository<Country>, ICountryRepository
{
public CountryRepository(CmsDbContext cmsDbContext)
: base(cmsDbContext) {}
}
interface IUnitOfWork : IDisposable
{
ICountryRepository CountryRepository { get; }
}
public class UnitOfWork : IUnitOfWork
{
private readonly CmsDbContext _context;
public UnitOfWork(CmsDbContext context)
{
_context = context;
CountryRepository = new CountryRepository(_context);
}
public ICountryRepository CountryRepository { get; private set; }
public int Commit()
{
return _context.SaveChanges();
}
public void Dispose()
{
_context.Dispose();
}
}
Now, in my ViewModel
private UnitOfWork Currentunitofwork;
Currentunitofwork = new UnitOfWork(new CmsDbContext());
I followed a description of a tutor in udemy.
Is this separation correct?
Move all repository (Entity framework) methods behind interfaces in the Core and reference those interfaces in the ViewModel project.
Core.dll
public class SomeModel {}
public interface ISomeModelRepositoryService
{
SomeModel GetById(int id);
void Save(SomeModel model);
}
Model.dll - this project implements Core's interfaces and contains only database methods (Entity framework in your case)
public class SomeModelRepositoryService : ISomeModelRepositoryService
{
public SomeModel GetById(int id)
{
//Entity framework code
}
public void Save(SomeModel model)
{
//Entity framework code
}
}
ViewModel.dll
public class SomeModelViewModel
{
private ISomeModelRepositoryService _RepositoryService;
public SomeModel Model { get; set; }
public SomeModelViewModel(ISomeModelRepositoryService repositoryService)
{
_RepositoryService = repositoryService;
}
public void Save()
{
_RepositoryService.Save(this.Model);
}
}
Create repository implementation instances in top startUp project(Main method for example) and put it to ViewModel as parameters:
ISomeModelRepositoryService repositoryService = new SomeModelRepositoryService();
SomeModelViewModel viewmodel = new SomeModelViewModel(repositoryService);
With this approach only "Model.dll" need to have references to Entity Framework
Related
All,
I'm using Unit Of Work and Generic Repository patterns for data access in my ASP.NET MVC app with Entity Framework 5. My app worked fine when I only had to deal with 1 database and DbContext.
My problem is, I have a second not-very-closely-related database I need data access for, so I'm assuming I need a second DbContext. However, I don't know how to refactor my Generic Repository to accommodate more than one DbContext. Help!
Here's a simplified look at what I'm attempting so with comments explaining what's failing:
public class UnitOfWork
{
private Db1Entities db1Context = new Db1Entities();
private Db2Entities db2Context = new Db2Entities();
public GenericRepository<ObjectA> ObjectARepository { // ObjectA is sourced from database 1, so it uses a different DbContext than ObjectB.
get {
return new GenericRepository<ObjectA>(db1Context);
}
}
public GenericRepository<ObjectB> ObjectBRepository { // ObjectB is sourced from database 2, so it uses a different DbContext than ObjectA.
get {
return new GenericRepository<ObjectB>(db2Context);
}
}
}
public class GenericRepository<T> where T : class
{
internal DbContext context; // This line and the GenericRepository constructor are my problem. Type DbContext, being a base class, doesn't have the db objects that Db1Entities or Db2Entities have.
// When I used to only have to manage 1 DbContext, "context" was type Db1Entities and it worked fine.
internal DbSet<T> dbSet;
public GenericRepository(DbContext context) {
this.context = context;
this.dbSet = context.set<T>();
}
public virtual T GetByID (int id) {
// code to return a T object by id...
}
// Other repository methods...
}
FYI this is what I'm doing to get by for now. I don't consider it a solution because I'm duplicating "GenericRepository" by copying it as 2 generic repositories, each designed for a different DbContext. I think I ought to be able to use "GenericRepository" and be able to pass it a DbContext rather than making a GenericRepository class for each DbContext... I just don't know how to make it work. See below:
public class UnitOfWork
{
private Db1Entities db1Context = new Db1Entities();
private Db2Entities db2Context = new Db2Entities();
public GenericDb1Repository<ObjectA> ObjectARepository { // ObjectA is sourced from database 1, so it uses a different DbContext than ObjectB.
get {
return new GenericDb1Repository<ObjectA>(db1Context);
}
}
public GenericDb2Repository<ObjectB> ObjectBRepository { // ObjectB is sourced from database 2, so it uses a different DbContext than ObjectA.
get {
return new GenericDb2Repository<ObjectB>(db2Context);
}
}
}
public class GenericDb1Repository<T> where T : class
{
internal Db1Entities context;
internal DbSet<T> dbSet;
public GenericRepository(Db1Entities context) {
this.context = context;
this.dbSet = context.set<T>();
}
public virtual T GetByID (int id) {
// code to return a T object by id...
}
// Other repository methods...
}
public class GenericDb2Repository<T> where T : class
{
internal Db2Entities context;
internal DbSet<T> dbSet;
public GenericRepository(Db2Entities context) {
this.context = context;
this.dbSet = context.set<T>();
}
public virtual T GetByID (int id) {
// code to return a T object by id...
}
// Other repository methods...
}
public class GenericDb1Repository<T, TContext>
where T : class
where TContext : DbContext, new()
{
internal TContext context;
internal DbSet<T> dbSet;
public GenericRepository(TContext context) {
this.context = context;
this.dbSet = context.set<T>();
}
public virtual T GetByID (int id) {
// code to return a T object by id...
}
// Other repository methods...
}**
My project has NLayer architecture.
My persistence layer is dependent on the domain layer but the domain layer has no knowledge of the entity models.
Similarly my business layer is dependent on the domain layer and has no knowledge of entity models.
While writing the business layer, I apply some predicate logic to filter the data in repository.
But this predicate logic is applied using domain model Expression<Func<TDomain, bool>> and Entity Framework works on with Expression<Func<TEntity, bool>>.
How do I convert the predicate?
Is there any workaround to the problem?
Implementation Of Base Repository
namespace MyProject.Entity
{
public abstract class BaseRepository<TId, TDomain, TEntity> : IRepository<TId, TDomain>
where TId : struct
where TDomain : class
where TEntity : class
{
protected readonly DbContext _dbContext;
public BaseRepository(DbContext dbContext)
{
_dbContext = dbContext;
}
public void Add(TDomain objDomain)
{
var entityObj = objDomain.MapTo<TDomain, TEntity>();
_dbContext.Set<TEntity>().Add(entityObj);
objDomain = entityObj.MapTo<TEntity, TDomain>();
}
public void AddRange(IEnumerable<TDomain> domainObjects)
{
var entityObjects = domainObjects.Select(x => x.MapTo<TDomain, TEntity>());
_dbContext.Set<TEntity>().AddRange(entityObjects).ToList();
domainObjects = entityObjects.Select(x => x.MapTo<TEntity, TDomain>());
}
public void Delete(TId id)
{
var objectToRemove = _dbContext.Set<TEntity>().Find(id);
if (objectToRemove != null)
{
_dbContext.Set<TEntity>().Remove(objectToRemove);
}
}
public IEnumerable<TDomain> Find(Expression<Func<TDomain, bool>> predicate)
{
return _dbContext.Set<TEntity>().Where(predicate);
}
public TDomain Get(TId id)
{
return _dbContext.Set<TEntity>().Find(id).MapTo<TEntity,TDomain>();
}
public IEnumerable<TDomain> GetAll()
{
return _dbContext.Set<TEntity>().Select(x=>x.MapTo<TEntity,TDomain>()).ToList<TDomain>();
}
}
}
I have a Interface named IRepository and class named Repository to implement Repository pattern in C# MVC as
public interface IRepository<TEntity>
{
void Insert(TEntity entity);
void Delete(TEntity entity);
}
public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
{
DbSet<TEntity> DbSet;
TestDBEntities dataContext;
public Repository(TestDBEntities dataContext)
{
this.dataContext = dataContext;
this.DbSet = dataContext.Set<TEntity>();
}
public void Insert(TEntity entity)
{
DbSet.Add(entity);
dataContext.SaveChanges();
}
public void Delete(TEntity entity)
{
DbSet.Remove(entity);
}
public IQueryable<TEntity> SearchFor(Expression<Func<TEntity, bool>> predicate)
{
return DbSet.Where(predicate);
}
}
and here is my controller:
public class HomeController : Controller
{
private IRepository<Tbl_EmpDetails> _EmpDetails;
public HomeController()
{
_EmpDetails = new Repository<Tbl_EmpDetails>(new TestDBEntities());
}
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(Tbl_EmpDetails empDetials)
{
_EmpDetails.Insert(empDetials);
return Redirect("/");
}
}
As per my idea in controller i should not have to use "new TestDBEntities()" because instance of EDMX will be create again and again when Insert,Update,Delete or any another function of controller will call and there will be no use of Repository. (TestDBEntity is object of my EDMX).
_EmpDetails = new Repository<Tbl_EmpDetails>(new TestDBEntities());
Tbl_EmpDetails is an table under EDMX.
Please suggest me what is the perfect way to implement repository structure according to my code and also if you have any other Suggestion to improve my code.
Thanks in advance.
This is how i structure my project.
Project.Web
-> Controllers
Project.Domain
-> Contracts
-> Services
Project.Data
-> Contracts
-> Repositories
So in my controller, only the service was exposed (so all the implementations are encapsulated). I used ninject to handle this dependencies.
public SomeController(IService service)
{
}
INSIDE MY DOMAIN PROJECT
An interface and a class that derived that interface was implemented. So basically, this only calls the repository project and other business logic should reside here.
The interface
public interface IService
{
IEnumerable<SomeClass> FindAll();
}
The implementation
public class Service : IService
{
private ISomeRepository _someRepository; // Exposed instance of my repo
public IEnumerable<SomeClass> FindAll()
{
return _someRepository.FindAll();
}
}
INSIDE MY DATA PROJECT
I also have two implementations one for the interface and another one for the class which implementing this interface.
The interface
public interface ISomeRepository
{
IEnumerable<Some> FindAll();
}
The implementation
public class SomeRepository : BaseRepository, ISomeRepository
{
public R(IUnitOfWork unitOfWork)
: base(unitOfWork)
{
}
public IEnumerable<SomeClass> FindAll()
{
return this.GetDbSet<SomeClass>();
}
}
If you wonder what is the use of BaseRepository and UnitOfWork, this will holds the context of our model (EDMX).
Base Repository
public class BaseRepository
{
protected IUnitOfWork UnitOfWork { get; set; }
protected MyEntities Context
{
get { return (MyEntities)this.UnitOfWork.Database; }
}
public BaseRepository(IUnitOfWork unitOfWork)
{
if (unitOfWork == null) throw new ArgumentNullException("unitOfWork");
this.UnitOfWork = unitOfWork;
}
protected virtual DbSet<TEntity> GetDbSet<TEntity>() where TEntity : class
{
return this.Context.Set<TEntity>();
}
protected virtual void SetEntityState(object entity, EntityState entityState)
{
this.Context.Entry(entity).State = entityState;
}
}
Unit Of Work
public class UnitOfWork : IUnitOfWork, IDisposable
{
public DbContext Database { get; private set; }
public UnitOfWork(DbContext dbContext)
{
Database = dbContext;
}
public void SaveChanges()
{
Database.SaveChanges();
}
public void Dispose()
{
Database.Dispose();
}
}
The IUnitOfWork interface
public interface IUnitOfWork
{
DbContext Database { get; }
/// <summary>
/// Saves changes to all objects that have changed within the unit of work.
/// </summary>
void SaveChanges();
}
So for this, we cater the issue of separation of concerns and each project serves it's true purpose
I am currently implementing EF6 to replace the ADO connection that currently exists.
I have read articles on why I should/shouldn't use the Repository pattern.
However I'm still not sure how to correctly call the repository pattern.
My project is layered as:
Presentation
Business Layer
Business Objects
Data Access Layer
Web Services
In the DAL I add my EF6 connection to my DB.
I created a IRepository and Repository classes.
Should the Business Layer be the one to call the Repository class?
If so I'm missing the connection here on how to call it.
Repository class:
public class MyRepository<T> : IRepository<T> where T : class
{
protected DbSet<T> DbSet;
protected DbContext _context;
public MyRepository(DbContext dataContext)
{
_context = dataContext;
DbSet = dataContext.Set<T>();
}
#region IRepository
public int Save()
{
return _context.SaveChanges();
}
public void Insert(T entity)
{
DbSet.Add(entity);
}
public void Delete(T entity)
{
DbSet.Remove(entity);
}
public IQueryable<T> SearchFor(System.Linq.Expressions.Expression<Func<T, bool>> predicate)
{
return DbSet.Where(predicate);
}
public IQueryable<T> GetAll()
{
return DbSet;
}
public T GetById(int id)
{
return DbSet.Find(id);
}
#endregion
}
My goal is to have MyRepository handle the 6 or so tables that I added in EF.
Where I am missing is how to implement this class in my business access layer.
I get the error
'MyEFConn' is a 'type' but is used like a 'variable'
My attempt at implementing it is:
MyRepository<"table from EF"> users = new MyRepository<"table from EF">(MyEFConn);
Which MyEFConn is my DbContext class..
public partial class MyEFConn: DbContext
I get the error 'MyEFConn' is a 'type' but is used like a 'variable'
This is because the constructor for MyRepository expects to be passed an instance of a DbContext. In your case that would be an instance of MyEFConn.
Ex:
MyEfConn context = new MyEfConn();
MyRepository<MyUsers> users = new MyRepository<MyUsers>(context);
I am working on ASP.NET MVC 4 project from scratch. I decided to start with the data access layer using Entity Framework 5 and Code First workflow. The company where I used to work was using very good implementation (in my opinion) of the Repository pattern including Repositories, Services, Abstract Factory for the Repositories and the Services and Unity for DI. I tried to redo it but it's just too complicated for me and will cost me a lot of time to replicate what I've been using there, so I decided to do some research and go with something lighter.
So I decided to use GenericRepository and UnitOfWork - far from what was the initial plan, but that was the implementation that was showing in most of my searches. So I did a very basic implementation (Just to the point where I'm sure I know what's going on, maybe even below my abilities to comprehend) and actually I think for this exact project it may be just enough but what I want is to be able to call additional custom methods on the different entities.
I think this gets a lot from the idea of generic repository, but if I try to go with some other implementation it's getting exponentially harder, so I wonder if there's a way to add this to my implementation without hurting too much the idea behind the generic Repository.
What I have now is the GenericRepository class :
public class GenericRepository<TEntity> where TEntity : class
{
internal DBContext context;
internal DbSet<TEntity> dbSet;
public GenericRepository(DBContext context)
{
this.context = context;
this.dbSet = context.Set<TEntity>();
}
public virtual IEnumerable<TEntity> Get()
{
IQueryable<TEntity> query = dbSet;
return query.ToList();
}
//just the standard implementation
and my UnitOfWork class :
public class UnitOfWork : IDisposable
{
private DBContext context = new DBContext();
private CustomerRepository customerRepository;
public CustomerRepository CustomerRepository
{
get
{
if (this.customerRepository == null)
this.customerRepository = new CustomerRepository(context);
return customerRepository;
}
}
private GenericRepository<Order> orderRepository;
public GenericRepository<Order> orderRepository
{
get
{
So as you may see my Order entity is using the GenericRepository but I made a test class CustomerRepository to use for my Customer entity.
For now this class CustomerRepository looks like this :
public class CustomerRepository : GenericRepository<Customer>
{
public CustomerRepository(DBContext context) : base(context) { }
}
and the idea is to add the methods that are explicitly for the Customer entity here. I'm not sure if this is correct, especially the way I call the constructor. However, what is the natural way to add those specific methods for the different entities? I don't mind to even take a step back to implement it better but I don't want to rush it cause I tried and at the moment the whole concept is too complicated for me and I want to be sure that I understand the things that I use in my code.
I think you are on the right track. Here is the generic repository that I use:
public interface IRepository<TEntity>
where TEntity : class
{
IQueryable<TEntity> GetAll();
IQueryable<TEntity> GetBy(Expression<Func<TEntity, bool>> predicate);
TEntity GetById(long id);
void Add(TEntity entity);
void Update(TEntity entity);
void Delete(TEntity entity);
}
public class Repository<TEntity> : IRepository<TEntity>
where TEntity : class
{
protected readonly DbEntities Context;
protected readonly DbSet<TEntity> Set;
public Repository()
{
Context = new DbEntities();
Set = Context.Set<TEntity>();
}
public virtual IQueryable<TEntity> GetAll()
{
return Set;
}
public virtual IQueryable<TEntity> GetBy(Expression<Func<TEntity, bool>> predicate)
{
return Set.Where(predicate);
}
public virtual TEntity GetById(long id)
{
return Set.Find(id);
}
public virtual void Add(TEntity entity)
{
Set.Add(entity);
Context.SaveChanges();
}
public virtual void Update(TEntity entity)
{
Set.Attach(entity);
Context.Entry(entity).State = EntityState.Modified;
Context.SaveChanges();
}
public virtual void Delete(TEntity entity)
{
Set.Remove(entity);
Context.SaveChanges();
}
}
// And assuming User is a data object with an Id property:
public interface IUserSpecificRepository
{
List<User> GetById(long id)
}
public class UserSpecificRepository : IUserSpecificRepository, Repository<User>
{
public virtual List<User> GetById(long id)
{
return GetBy(x => x.Id = id).ToList();
}
}
Notice that GetAll() and GetBy() return a queryable. This is to allow control of when the query expression gets converted to SQL and hits the database. Usually a call to ToList() will cause this. You can then inherit from this and any custom methods can make use of these two starter methods.
Also, As a general rule of thumb, you should never do a GetAll().ToList() like you have now. If you have a zilion records you will run into problems. It is also a performance issue if you are filtering down to a few records. GetAll().ToList().Where(x => x.Id = 1) basically gets all zillion records from the db into memory, then filters it down to one. You should instead do this GetAll().Where(x => x.Id = 1).ToList().
Hope this helps you along!