ASP.NET MVC - 放置数据库查询的位置

jan*_*naj 7 .net asp.net asp.net-mvc asp.net-mvc-4

我正在尝试学习ASP.NET MVC 4,我很困惑我应该把数据库查询放在哪里.我有PHP背景,特别是CodeIgniter,我习惯于将所有数据库查询放入模型中.我有这个问题:

    db.Orders.Where(order => order.columnName == columnName).SingleOrDefault();
Run Code Online (Sandbox Code Playgroud)

基于这个ASP.NET教程,我应该把它放在控制器中.但是,我发现了这个StackOverflow问题,它说我应该把它放在模型中(类似于我以前在PHP中做的).对同一问题的另一个答案提到了创建包含所有查询的存储库模式/类.

所以我的问题是,在代码维护(可读性,更改效果等)方面,以下选项的优缺点是什么?

  1. 控制器中的查询
  2. 模型中的查询
  3. 在单独的类/层中查询

Shy*_*yju 4

使用存储库模式处理此问题的简单方法。这不是最好的方法。但会让您了解如何使用存储库模式来处理这个问题。

创建一个存储库来执行所有数据库事务

public interface IRepository
{
  Order GetOrder(int orderId);
}
public class Repository : IRepository
{
   YourDBContext db;
   public Repository()
   {
      db = new YourDBContext ();
   }
   public User GetOrder(int orderId)
   {
      return db.Orders.FirstOrDefault(s=>s.OrderID==orderId);
   }
}
Run Code Online (Sandbox Code Playgroud)

您可以在同一项目中(在“数据访问逻辑”下)创建它,或者为此创建一个单独的类库(并在您使用它的任何地方引用它)。

现在在您的控制器中,导入必要的名称空间后,只需创建存储库的一个对象并调用您感兴趣的方法

public OrderController :Controller
{
  protected IRepository repo;
  public OrderController()
  {
    repo=new Repository();
  }
  public OrderController(IRepository repositary)
  {
    // This constructor is for your Unit test project, 
    // you can pass a mock repository here
    // Read dependency injection
    repo=repository;
  }
  public ActionResult details(int id)
  {
    var order=repo.GetOrder(id);
    if(order!=null)
    {
      return View(order);
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

如果您认为您的视图需要它,您可以考虑使用视图模型。在这种情况下,您需要从域对象中读取属性值并将其设置为视图模型的实例并将其返回到您的视图。

随着代码/功能的增长,您可以将代码移动到不同的类/层/项目。