Реализация и использование универсального репозитория ASP.NET MVC - PullRequest
0 голосов
/ 30 ноября 2018

Я решил разработать общий репозиторий внутри моего приложения ASP.NET MVC, тем не менее, у меня есть некоторые проблемы с реализацией.Я попытаюсь описать мою проблему ниже.

Это мой общий репозиторий:

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 interface IArtistRepository : IGenericRepository<Artist>
{
    Artist GetSingle(int fooId);
}

public abstract class GenericRepository<C, T> : IGenericRepository<T> where T : class where C : DbContext, new()
{
    public C Context { get; set; } = new C();

    public virtual IQueryable<T> GetAll()
    {
       IQueryable<T> query = Context.Set<T>();
       return query;
    }

    public IQueryable<T> FindBy(System.Linq.Expressions.Expression<Func<T, bool>> predicate)
    {
       IQueryable<T> query = Context.Set<T>().Where(predicate);
       return query;
    }

    public virtual void Add(T entity)
    {
       Context.Set<T>().Add(entity);
    }

    public virtual void Delete(T entity)
    {
       Context.Set<T>().Remove(entity);
    }

    public virtual void Edit(T entity)
    {
       Context.Entry(entity).State = EntityState.Modified;
    }

    public virtual void Save()
    {
       Context.SaveChanges();
    }
}

Конкретные реализации:

public class ArtistRepository :
      GenericRepository<MusicContextSqlServer, Artist>, IArtistRepository
{

    public Artist GetSingle(int artistId)
    {
       var query = GetAll().FirstOrDefault(x => x.ArtistId == artistId);
       return query;
    }
}    

Теперь, когда строим контроллер, давайте возьмем Artistконтроллер в качестве примера:

Это будет конструктор:

public class ArtistsController : Controller
{
     private readonly IArtistRepository _artistRepo;

     public ArtistsController(IArtistRepository artistRepo)
     {
         _artistRepo = artistRepo;
     }
}

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

public ActionResult Index()
{
    var model = _artistRepo.GetAll();
    return View(model.ToList());
}

однако мне также нужновключить ArtistDetails dbset, обычно используя контекст, встроенный в контроллер. Я мог бы сделать так:

(в этом случае db - это обычный контекст, встроенный в контроллер)

public ActionResult Index()
{
    var artist = db.Artist.Include(a => a.ArtistDetails);                     
    return View(artist.ToList());
}

Но после использования репозиториевЯ не уверен, где можно добавить эту функцию Include(), чтобы она работала в моих репозиториях.На данный момент я могу просто сделать GetAll() из моего хранилища.Та же ситуация с вызовом db.ArtistDetails внутри SelectList.

Такая же ситуация с Create, обычно я бы использовал: (в этом случае db - это обычный контекст, встроенный в контроллер)

public ActionResult Create()
{
     ViewBag.ArtistId = new SelectList(db.ArtistDetails, "ArtistId", "Bio");       
     return View();       
}

public ActionResult Create([Bind(Include = "ArtistId,Name")] Artist artist)
{
      if (ModelState.IsValid)
      {
          db.Artist.Add(artist);
          db.SaveChanges();
          return RedirectToAction("Index");
      }

      ViewBag.ArtistId = new SelectList(db.ArtistDetails, "ArtistId", "Bio", artist.ArtistId);

       return View(artist);
}

Как я могу конвертировать эти методы, используя репозитории, которые я использую.Обобщая, как изменить эти методы после того, как я внедрил свой репозиторий, где я должен внести изменения и как это будет выглядеть, кто-нибудь может показать решение в качестве ответа.Спасибо.

1 Ответ

0 голосов
/ 30 ноября 2018

Поскольку вы наследуете публичное свойство Context, которое будет доступно для использования репозиторием художника.Я бы представил другой метод для Artist repository, как показано ниже:

public Artist GetSingleWithDetails(int artistId)
    {
       return = Context.Set<Artist>().Include(a => a.ArtistDetails).FirstOrDefault(x => x.ArtistId == artistId);

    }

В идеале Context свойство должно быть защищено так, чтобы оно было доступно подклассам, но не доступно публично

EDIT : для ArtistDetailsRepository для GetAll ArtistDetails

Интерфейс:

public interface IArtistDetailsRepository : IGenericRepository<ArtistDetails>
{        
}

Репозиторий:

public class ArtistDetailsRepository :
      GenericRepository<MusicContextSqlServer, ArtistDetails>, IArtistDetailsRepository
{   
}    

Создать:

ViewBag.ArtistId = new SelectList(artistDetailRepository.GetAll.ToList(), "ArtistId", "Bio", artist.ArtistId);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...