2016-07-14 4 views
0

У меня есть интерфейс с именем IRepository и класс с именем Repository для реализации Repository шаблона в C# MVC, какНевозможно использовать правильную Generic Repository структуры C# MVC С Entity Framework

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); 
     } 

    } 

и вот мой контроллер:

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("/"); 
    } 

} 

Согласно моей идее в контроллере, я не должен использовать «новые TestDBEntities()», потому что экземпляр EDMX будет создаваться снова и снова, когда вставка, обновление, удаление или любая другая функция контроллера вызовет и не будет использование репозитория. (TestDBEntity является объектом моего EDMX).

_EmpDetails = new Repository<Tbl_EmpDetails>(new TestDBEntities()); 

Tbl_EmpDetails представляет собой таблицу под EDMX.

Просьба предложить мне, что является идеальным способом реализации структуры репозитория в соответствии с моим кодом, а также если у вас есть другие предложения по улучшению моего кода.

Заранее спасибо.

+0

очень полезно взглянуть на http://www.asp.net/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc -4/реализации-The-хранилищу и единичную из-человеко-моделей-в-в-Asp-нетто-MVC-приложения. он описывает изменение использования репозитория вместо прямого контекста шаг за шагом. –

ответ

0

Вот как я структурирую свой проект.

Project.Web 
    -> Controllers 

Project.Domain 
    -> Contracts 
    -> Services 

Project.Data 
    -> Contracts 
    -> Repositories 

Таким образом, в моем контроллере, только сервис был оголенные (так что все реализации инкапсулируются). Для обработки этих зависимостей я использовал ninject.

public SomeController(IService service) 
{ 
} 

ВНУТРИ мой домен ПРОЕКТ

интерфейс и класс, который получен, что интерфейс был реализован. Таким образом, в основном, это только вызов проекта репозитория и другая бизнес-логика должны находиться здесь.

Интерфейс

public interface IService 
    { 
     IEnumerable<SomeClass> FindAll(); 
    } 

Реализация

public class Service : IService 
    { 
     private ISomeRepository _someRepository; // Exposed instance of my repo 

     public IEnumerable<SomeClass> FindAll() 
     { 
      return _someRepository.FindAll(); 
     } 
    } 

ВНУТРИ МОЕГО ДАННЫЕ ПРОЕКТА

У меня также есть две реализации одного для интерфейса и еще один для класс, который используя этот интерфейс.

Интерфейс

public interface ISomeRepository 
    {   
     IEnumerable<Some> FindAll(); 
    } 

Реализация

public class SomeRepository : BaseRepository, ISomeRepository 
    { 
     public R(IUnitOfWork unitOfWork) 
      : base(unitOfWork) 
     { 

     } 

     public IEnumerable<SomeClass> FindAll() 
     { 
      return this.GetDbSet<SomeClass>(); 
     } 
    } 

Если вам интересно, что является использование BaseRepository и UnitOfWork, это будет справедливо контекст нашей модели (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; 
      } 
     } 

единицы работы

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(); 
     } 
    } 

Интерфейс IUnitOfWork

public interface IUnitOfWork 
    { 
     DbContext Database { get; } 

     /// <summary> 
     /// Saves changes to all objects that have changed within the unit of work. 
     /// </summary> 
     void SaveChanges(); 
    } 

Так для этого, мы обслуживаем вопрос о разделении концерна s и каждый проект служит его истинному назначению

+0

Спасибо Desperado, но я просто хочу подтвердить, что мои реализации в порядке или что мне нужно для улучшения моего кода ... По словам вас, я делаю правильные реализации ?? Особенно в конструкторе контроллера, добавив «new TestDBEntities()». –

+0

@AmandeepSingh, который не прав, контроллер не должен напрямую изменять контекст, потому что, если в дальнейшем появятся какие-либо бизнес-логики, контроллер будет переполнен, и нам это не нравится – Sherlock

+0

OK @ Desperado, Еще раз спасибо. Можете ли вы изменить мой код в лучшую структуру как можно проще? поскольку я новичок в этой концепции. –