В шаблоне Generic Repository повторяется код, и что будет полезно?

Я понимаю шаблон репозитория в С#. Я смущен, когда я изучаю общий шаблон репозитория. В нем много повторений. У меня есть вопрос об этом шаблоне.

Я использую первый подход для кода Entity Framework, и у меня есть два класса модели

Student Учителя

Сколько общих интерфейсов я буду использовать, например, если у меня есть один  общий интерфейс

public interface IRepository<tentity>
{
 IQueryable<tentity> FindAll(Expression<func<tentity, bool="">> where = null);
 TEntity FindOne(Expression<func<tentity, bool="">> where = null); 
}
</func<tentity,></func<tentity,></tentity></tentity>

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

public class StudentRepo<tentity> : IRepository<tentity> where TEntity : class
{
 public virtual IQueryable<tentity> FindAll(Expression<func<tentity, bool="">> where = null)
 {
 return null != where ? Context.Set<tentity>().Where(where) : Context.Set<tentity>();
 }
 public virtual TEntity FindOne(Expression<func<tentity, bool="">> where = null)
 {
 return FindAll(where).FirstOrDefault();
 }
 public void update()
 {
 }
 public int FindId()
 {
 }
}
</func<tentity,></tentity></tentity></func<tentity,></tentity></tentity></tentity>

Итак, я добавил два новых метода update() и FindId() в StudentRepo, где я могу определить эти методы?

Если я хочу добавить эти два метода в IRepository, тогда я должен вызвать эти методы для класса Учителя. что будет выгодно для него? Это лучший подход, если я создаю отдельный интерфейс для обоих классов? как IStudent и ITeacher, поэтому я могу определить те методы, которые я хочу использовать, и ненужные методы не будут использоваться.

Прошу прощения, я так запутался.

3 ответа

Общие хранилища бесполезны. Они просто делают то же самое, что и структура сущности, и большинство реализаций там раскрывают IQueryable.

Так почему же так плохо?

Шаблон репозитория используется для создания абстракции между источником данных и вашим кодом. Эта абстракция создана для уменьшения сложности и уменьшения связи между этими уровнями.

Обычно общий репозиторий может показаться хорошим выбором, но поскольку каждый объект (корневой агрегат) имеет свои собственные уникальные функции, вам всегда придется писать собственные запросы для их извлечения.

Чтобы решить эту проблему, большинство общих реализаций выставляют IQueryable. Это плохо, так как нет ни одного 100% -ного поставщика Linq to Sql (набор классов, который переводит оператор LINQ в инструкцию SQL). Каждому провайдеру приходится прибегать к пользовательским командам для поддержки нетерпеливой/ленивой загрузки, поддержки предложения IN sql и т.д.

Вы всегда должны знать об этих настройках каждый раз, когда используете репозиторий через IQueryable.

Следовательно, вам все равно нужно знать, как работает Entity Framework. Поэтому вы можете использовать EF напрямую, а не использовать общий репозиторий.

Если вы действительно хотите использовать шаблон репозитория, сначала создайте свой код со всеми вашими классами. И ТОГДА создайте базу данных. То есть, установите DB после кода, а не наоборот. И убедитесь, что ваш репозиторий - полная абстракция на 100% (например, google persistance ignorance)


У вас может быть одна реализация для IRepository, которая у вас есть, например:

public class GenericRepository<tentity> : IRepository<tentity> where TEntity : class
{
 public virtual IEnumerable<tentity> FindAll(Expression<func<tentity, bool="">> where = null)
 {
 // implementation ...
 }
 public virtual TEntity FindOne(Expression<func<tentity, bool="">> where = null)
 {
 // implementation
 }
 public void Update(TEntity entity)
 {
 // update your entity ...
 }
 // etc...
}
</func<tentity,></func<tentity,></tentity></tentity></tentity>

Затем у вас есть собственный репозиторий:

public class StudentRepository : GenericRepository<student>
{
 // here you get all the goodies + you can add your own stuff
}
</student>

и

public class TeacherRepository : GenericRepository<teacher>
{
 // here you get the same goodies, you don't need to re-implement them
}
</teacher>

Таким образом, вам не нужно повторно реализовывать все методы, определенные в общем репозитории, однако вы можете добавить свои собственные более сложные методы.


Я думаю, что идея Generic Repository пытается обобщить слишком много, отдельные интерфейсы лучше, на мой взгляд, поскольку они обеспечивают более значимый контракт, этот блог объясняет это очень хорошо и предлагает использовать общий репозиторий "за кулисами".

licensed under cc by-sa 3.0 with attribution.