我正在尝试了解如何使用存储库构建ASP.Net MVC2 Web App。
我阅读的很多示例,教程和书籍都是如此构建应用程序:
public interface IProductsRepository
{
IQueryable<Product> Products { get; }
}
public class SqlProductsRepository : IProductsRepository
{
public Table<Product> productsTable;
public IQueryable<Product> Products
{
get { return productsTable }
}
}
public class ProductsController : Controller
{
IProductsRepository productsRepository;
public ProductsController(IProductsRepository productsRepository)
{
// set the Repository
}
public ActionResult GetLatestPublishedProducts(int pageSize, int page, ref int totalItemCount)
{
// Do LINQ query
return View(from p in productsRepository
where p.PublishedOn != null
orderby p.ProductId descending
select to(p))
.Skip((page - 1) * pageSize)
.Take(pageSize)
.ToList());
}
}
我不明白的一件事是为什么Linq查询存在于控制器中。
我想知道为什么做这样的事情是不对的:
public class SqlProductsRepository : IProductsRepository
{
// set data model stuff here
public List<Product> GetLatestPublishedProducts(int pageSize, int page, ref int totalItemCount) {
// DO LINQ Query in here
}
}
public class ProductsController : Controller
{
// set repository stuff here
public ActionResult GetLatestPublishedProducts(int pageSize, int page, ref int totalItemCount)
{
return View(productsRepository.GetLatestPublishedProducts(pageSize, page, totalItemCount));
}
}
答案 0 :(得分:7)
你的第二个例子就是你应该做的事情。存储库应处理所有数据访问。
控制器应该只获取已经过滤/排序的数据并将其传递给视图。控制器不应该对任何数据或业务逻辑负责。它应该只负责检索数据并传递它。
在控制器中编写代码时,我问自己这个问题;
我是否必须再次编写此代码 如果我要写这个应用程序 的WinForms?
因此,您的IProductsRepository
将拥有GetLatestPublishedProducts
方法,然后您将在SqlProductsRepository
中实施该方法。
责任是:
然后,您可以更进一步,将任何业务逻辑分离出来,以便Controller本身避免使用存储库。因此,您将拥有位于Controller和存储库之间的第三个服务层。
答案 1 :(得分:4)
检查不同类别的意图。
这意味着,如果您将Linq视为您的主要业务逻辑,那么它应该不是2中的任何一个。 我会创建一个ProductService,它包含所有这些抽象的调用,因为它们将被重复使用。
服务应该是什么:
from p in productsRepository
where p.PublishedOn != null
orderby p.ProductId descending
select to(p))
控制器应该是什么:
from p in productService.GetLatestPublishedProducts()
.Skip((page - 1) * pageSize)
.Take(pageSize)
如果可能的话,使用IEnumerable。不是清单。
答案 2 :(得分:1)
实现保持控制器精益的目标。这有助于保持秩序井然有序。使用存储库来处理所有数据访问逻辑。我还包括一个服务层来处理其他业务和验证逻辑。因此,像Create这样的控制器,服务和存储库方法看起来像这样:
// Controller
public ActionResult Create(MyModel myModel)
{
if (!_service.CreateMyModel(myModel))
{
return View(myModel);
}
return RedirectToAction("Index");
}
// Service
public bool CreateMyModel(MyModel myModel)
{
// Validation logic
if (!ValidateMyModel(myModel))
{
return false;
}
return _repository.CreateMyModel(myModel);
}
// Repository
public book CreateMyModel(MyModel myModel)
{
_entities.AddToMyModelsSet(myModel);
try
{
_entities.SaveChages();
return true;
}
catch
{
return false;
}
}