存储过程业务逻辑应放在MVC中的哪个位置?

时间:2014-08-29 07:09:10

标签: asp.net asp.net-mvc entity-framework asp.net-mvc-5

我在这里寻找一些经验和解释,因为不同的来源给出了不同的建议。我是MVC的新手。我知道之前已经问过这个问题,但我(目前)并没有使用EF或Linq。

我有一个包含许多存储过程的SQL数据库。以前,当与webforms一起使用时,有一个业务层包含帮助程序方法,用于调用过程并将DataSet返回到页面。重要的是,程序经常审查约20个表格; 这些页面并不完全反映数据库结构(正如我在大多数MVC教程中看到的那样):

SQL database <--> stored procedures <--> business layer <--> web forms

我想采取最好的方法从正确的方面开始并正确学习,但感谢可能没有正确的答案。因此,如果你发帖,请你提供一些关于&#34;为什么&#34;?

的解释
  • 存储过程逻辑(SQLCommand / business methods等)应该在Model或 控制器?

One post advises neither,但保留业务层。 Another expert建议

  

[Models / Entities]不应该有什么插件方法   从数据库回来

  • 如果保留业务层,调用的方法在哪里(例如模型或控制器)?

  • 如果上面的答案是&#34;两者都没有&#34;,这是否意味着Model部件将不使用?

这几乎感觉事情并没有正确地完成 ,但在this tutorial似乎已经发生了什么。

  • 我应该将实体框架插入模型层以调用业务层吗?

这感觉有些过度,添加了所有额外的逻辑。

2 个答案:

答案 0 :(得分:1)

您的控制器应收集构建用户当前正在查看的页面所需的信息。就是这样。

控制器应该引用业务逻辑层中的类。

例如,这是你的控制器。它所做的就是翻译http请求并调用业务逻辑。

public class MyController : Controller
{
   private IMyBusinessLogic  _businessLogic;
   public MyController(IMyBusinessLogic businessLogic)
   {
      _businessLogic = businessLogic;
   }

   [HttpPost]
   public ActionResult UpdateAllRecords()
   {
      _businessLogic.UpdateAllRecords();
      return Json(new Success());
   }
}

您的业务逻辑类

public class MyBusinessLogic : IMyBusinessLogic  
{
  public void UpdateAllRecords()
  {
    // call SP here
    using(SqlConnection conn = new...
  }
}

这有很多好处:

  • 您的业务逻辑与您的UI完全分离,您的表示层中没有数据库代码。这意味着您的控制器可以专注于它的工作,代码不会受到污染。
  • 您可以测试您的控制器,看看当您的业务逻辑成功时会发生什么,抛出异常等。

要获得额外奖励积分,您应该考虑创建数据访问层。

public void DataAccess : IDataAccess
{
  public void RunStoredProcedure(string spName)
  {
  }
}

现在您可以测试您的BLL正在调用并正确处理您的SP结果!

在对模型提出质疑后对其进行了扩展: 理想情况下,你的模型根本就没有逻辑。它应该只表示构建页面所需的数据。您正在加载的对象表示系统中的实体,该模型表示页面上显示的数据。这通常要轻得多,并且可能包含主要实体不存在但显示在页面上的额外信息(例如地址)。

例如

public class Person
{
   public int  PersonID {get;set;}
   public string Firstname {get;set;}
   public string Lastname {get;set;}
   public Address Address {get;set;}
}

模型仅包含您要显示的信息:

public class PersonSummaryModel
{
   public int  PersonID {get;set;}
   public string FullName {get;set;}
}

然后将模型传递给视图以显示它(在这种情况下可能在FullNames列表中)。很多人都使用mapper类在这两者之间进行转换,有些人在控制器中进行转换。

例如

public class PersonMapper
{
  public PersonSummaryModel Map(Person person)
  {
     return new PersonSummaryModel
     {
       PersonID = person.PersonID,
       FullName = string.Concat(person.Firstname, " ", person.Lastname)
     };
  }
}

您也可以在AutoMapper使用某些自动解决方案为您执行此步骤。

答案 1 :(得分:1)

您的控制器实际上只应参与编排视图构造。创建一个单独的类库,称为“数据访问层”或不太通用的东西,并创建一个类来处理调用存储过程,从结果中创建对象等。关于如何处理它有很多意见,但也许是最

View
|
Controller
|
Business Logic
|
Data Access Layer
|--- SQL (Stored procs)
       -Tables
       -Views
       -etc.
|--- Alternate data sources
       -Web services
       -Text/XML files
       -and son on.

如果你想学习等级和最好的方法 MSDN在此链接上有很棒的文章 MSDN