В какой момент вы решили создать новый репозиторий? - PullRequest
1 голос
/ 29 июля 2011

Скажем, у вас есть эти два класса.

public class Author
{
public int ID {get; set;}
public string Name{get; set;}
public virtual ICollection<Book> Books { get; set;}
}

public class Book
{
public int ID {get; set;}
public string Name{get; set;}
public int AuthorId {get; set;}
public virtual Author Author{ get; set;}
}

Если у меня есть BooksController, в котором все его действия получают AuthorId

Я иду по этому адресу:

/ Авторы / 1 / Книги

Имеет ли смысл просто использовать текущий AuthorRepository?

public ActionResult Index(int AuthorId)
    {
    return View(_AuthorRepository.GetById(AuthorId).Books)
    }

Или для сохранения доступа к данным внутри репозиториев я должен создать BookRepository?

public ActionResult Index(int AuthorId)
    {
    return View(_BookRepository.GetByAuthorId(AuthorId))
    }

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

[HttpPost]
public ActionResult Create(int AuthorId, BookViewModel book)
{
if(ModelState.IsValid)
{
Book b= new Book();
b= AutomapperMagicMethodThatGivesMeABookFromA(book); //
_AuthorRepository.FindById(AuthorId).Books.Add(b);
_AuthorRepository.SaveChanges();
return RedirectToAction("Index");
}
return View(book)
}

Или такой подход.

[HttpPost]
public ActionResult Create(int AuthorId, BookViewModel book)
{
if(ModelState.IsValid)
{
Book b= new Book();
b= AutomapperMagicMethodThatGivesMeABookFromA(book); //
b.AuthorId = AuthorId;
_BookRepository.Add(b);
_BookRepository.SaveChanges();
return RedirectToAction("Index");
}
return View(book)
}

Буду признателен за несколько советов по обработке таких сценариев. Не стесняйтесь критиковать мой код столько, сколько хотите.

Пожалуйста, помогите спасибо заранее.

пс. Я использую EF, если это имеет значение.

Ответы [ 2 ]

3 голосов
/ 29 июля 2011

Общее правило - создать один репозиторий на корень совокупности .

Где сводный корень можно рассматривать как «родительский»,и «потомок» не может существовать без родителя.

В вашем примере Author является совокупным корнем, поскольку Book не может существовать без Автор .(FK доказывает это).

Следовательно, у вас должен быть LibraryRepository , способный работать как с авторами, так и с книгами, с одним набором объектов Entity Framework.

Мы фактически применяем эти совокупные границы в нашем Репозитории, вводя ObjectSet в универсальный тип в Репозитории.

Таким образом, вы можете иметь:

public class LibraryRepository : IRepository<Author>, GenericRepository<Author>
{
   public Author FindById(int id)
   {
      return _context.SingleOrDefault(x => x.AuthorId == id);
   }

   public Book FindById(int bookId)
   {
      return _context
         .Where(x => x.Books.Any(y => y.BookId == bookId))
         .Select(x => x.Books.SingleOrDefault(x => x.BookId == bookId))
         .SingleOrDefault();
   }
}

В приведенном выше примере _context - это свойство protected в универсальном репозитории, которое набирается как ObjectSet<Author> (что в T в универсальном репозитории).

Однако, посмотрите, как это грязно, найти книгу.Если вы обнаружите, что нуждаетесь в том, чтобы найти «ребенка» самостоятельно (например, не извлекая сначала родителя), то вам следует подумать и о создании хранилища книг.

Так что это сводится к двум вещам:

  1. Обеспечение совокупных границ
  2. Создание репозиториев, обслуживающих ваше приложение

Подумайте об интерфейсе пользователя, какая информация нужна каждому экрану, какая информация у него есть нарукой, чтобы идентифицировать эту часть информации (например, URL).

0 голосов
/ 29 июля 2011

Я бы посмотрел на это в аспекте модульного тестирования. Какой метод обеспечивает более простой способ тестирования контроллеров и проверки результатов тестирования в вашем коде?

...