假设你有这两个类。
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))
}
Create动作也会发生同样的事情。我很难决定哪一个更有意义。
[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)
}
我很感激有关处理此类情况的一些建议。 随意批评我的代码,尽可能多。
请提前帮助谢谢。
PS。我使用EF,如果它有任何区别。
答案 0 :(得分:3)
一般的经验法则是为每个聚合根创建一个存储库。
聚合根可以被认为是“父”,如果没有父母就不能存在“孩子”。
在您的示例中,作者是聚合根,因为如果没有作者,图书就不能存在。 (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
。< / p>
然而,看看如何找到一本书很麻烦。如果你发现自己需要自己找一个“孩子”(例如没有先检索父母),那么你也应该考虑创建一个书库。
所以它归结为两件事:
考虑用户界面,每个屏幕需要哪些信息,手头有哪些信息来识别该信息(例如URL)。
答案 1 :(得分:0)
我会在单元测试方面看一下。哪种方法可以更简单地测试控制器并验证代码中的测试结果?