在什么时候您决定应该创建一个新的Repository ?



假设你有这两个类。

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

我希望你能给我一些处理这种情况的建议。请随意批评我的代码。

请帮忙提前谢谢。

p。如果有区别的话,我用EF

一般的经验法则是为每个聚合根创建一个存储库。

其中聚合根可以被认为是"父",并且"子"不能没有父而存在。

在您的示例中,Author是聚合根,因为如果没有AuthorBook就不可能存在。(FK证明了这一点)

因此,您应该只拥有一个LibraryRepository,它能够使用单个实体框架对象集同时处理作者和图书。

我们实际上通过将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)

我会从单元测试的角度来看待它。哪种方法更容易测试控制器并验证代码中的测试结果?

相关内容

最新更新