2

我正在尝试使用没有 EF 并且可能没有 LINQ 的 ASP.NET MVC。首先,我在 VS2010 中的基本 ASP.net mvc 模板上只创建了一个表/模型/控制器/视图(仅实现了索引页面和索引方法)。我目前正在尝试/错误,因为网络上的所有教程都基于 EF,并且我有嵌入式 c 背景。

我的问题是:

  • 架构是否正确?

  • 我看到存储库模式用于一些开源项目,例如 nearforums。它的优势是什么,它如何适应这一点,它会取代 DAL 吗?

  • 我应该将数据表传递给视图还是表示数据表的对象?

  • 我可以将多个模型传递到剃须刀页面吗?例如,我如何列出 2 个不同的表?

  • 将所有 DAL 代码放在一个文件中更好吗?

达尔:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
using System.Configuration;
using MySql.Data.MySqlClient;

namespace MvcApplication1.Models
{
  public class DAL
  {
    public DAL()
    { }
    public DataTable getDataTable(string tableName)
    {
      using (MySqlConnection conn = new MySqlConnection(ConfigurationManager.ConnectionStrings["MySQLConn"].ConnectionString))
      {
        using (MySqlCommand command = conn.CreateCommand())
        {
          command.CommandText = "select * from " + tableName;
          command.CommandType = CommandType.Text;

          conn.Open();

          var table = new DataTable();
          table.Load(command.ExecuteReader());

          return table;
        }
      }
    }
  }
}

Product.cs 类表示代码中的 Product 表:

namespace MvcApplication1.Models
{
  public class Product
  {
      public int ProductId { get; set; }
      public string Name { get; set; }
      public string Producer { get; set; }
      public int UnitPrice { get; set; }
  }
}

产品控制器.cs

namespace MvcApplication1.Controllers
{
    public class ProductController : Controller
    {
        //
        // GET: /Product/
      DAL dal = new DAL();
        public ActionResult Index()
        {
          DataTable dt = dal.getDataTable("Product");
          Product[] products = new Product[dt.Rows.Count];
          for (int i = 0; i < dt.Rows.Count; i++)
          {
            products[i] = new Product();
            products[i].ProductId = (int)dt.Rows[i]["ProductId"];
            products[i].Name = (string)dt.Rows[i]["Name"];
            products[i].Producer = (string)dt.Rows[i]["Producer"];
            products[i].UnitPrice = Decimal.ToInt32((decimal)dt.Rows[i]["UnitPrice"]);
          }

          return View(products);
        }
........
........
}

索引.cshtml:

@model IEnumerable<MvcApplication1.Models.Product>
@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>
@foreach (var item in Model)
{
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.ProductId)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Name)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Producer)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.UnitPrice)
        </td>
        <td>
            @Html.ActionLink("Edit", "Edit", new { id=item.ProductId }) |
            @Html.ActionLink("Details", "Details", new { id=item.ProductId }) |
            @Html.ActionLink("Delete", "Delete", new { id=item.ProductId })
        </td>
        <br>
    </tr>
}
4

1 回答 1

3

我看到存储库模式用于一些开源项目,例如 nearforums。它的优势是什么,它如何适应这一点,它会取代 DAL 吗?

存储库模式的好处是它允许您切换数据访问逻辑/ORM。例如,如果您想从 Entity Framework 切换到 NHibernate,您只需在 IoC 容器中更新您的注册,就像魔术一样,您的代码正在使用 NHibernate,而您不知道是否进行过切换。它允许您的代码与底层持久性框架无关。据它所知,结果代码来自文件、Web 服务调用或内存列表。如果您必须从另一个组件进行相同的查询,您还将获得重用。另一个好处是单元测试。使用您当前的实现,您无法对控制器进行单元测试,因为它每次都将直接连接到您的数据库,因此根据定义使其成为集成测试。你肯定会想要利用 ORM,或者你会一遍又一遍地编写相同的代码,直到它让你哭泣。设置/拆除连接,将所有原语类型转换为原生 .NET 类型等。如今,处理原生 ADO.NET 已成为过去。使用 ORM 让您的生活更轻松。同时,权力越大,责任越大。如果您不验证针对数据库生成和执行的查询,ORM 可能是一场噩梦。如果使用不当,它们会产生性能问题。您将能够利用 LINQ 来处理大多数查询,但有时您必须使用肮脏的时髦本机并使用原始 SQL。您的 ORM 仍然能够处理这两种情况。设置/拆除连接,将所有原语类型转换为原生 .NET 类型等。如今,处理原生 ADO.NET 已成为过去。使用 ORM 让您的生活更轻松。同时,权力越大,责任越大。如果您不验证针对数据库生成和执行的查询,ORM 可能是一场噩梦。如果使用不当,它们会产生性能问题。您将能够利用 LINQ 来处理大多数查询,但有时您必须使用肮脏的时髦本机并使用原始 SQL。您的 ORM 仍然能够处理这两种情况。设置/拆除连接,将所有原语类型转换为原生 .NET 类型等。如今,处理原生 ADO.NET 已成为过去。使用 ORM 让您的生活更轻松。同时,权力越大,责任越大。如果您不验证针对数据库生成和执行的查询,ORM 可能是一场噩梦。如果使用不当,它们会产生性能问题。您将能够利用 LINQ 来处理大多数查询,但有时您必须使用肮脏的时髦本机并使用原始 SQL。您的 ORM 仍然能够处理这两种情况。拥有权利的同时也被赋予了重大的责任。如果您不验证针对数据库生成和执行的查询,ORM 可能是一场噩梦。如果使用不当,它们会产生性能问题。您将能够利用 LINQ 来处理大多数查询,但有时您必须使用肮脏的时髦本机并使用原始 SQL。您的 ORM 仍然能够处理这两种情况。拥有权利的同时也被赋予了重大的责任。如果您不验证针对数据库生成和执行的查询,ORM 可能是一场噩梦。如果使用不当,它们会产生性能问题。您将能够利用 LINQ 来处理大多数查询,但有时您必须使用肮脏的时髦本机并使用原始 SQL。您的 ORM 仍然能够处理这两种情况。

我应该将数据表传递给视图还是表示数据表的对象?

您当然不想传递数据表。您想将视图模型或实体传递给您的视图。视图应该对数据库一无所知。你所做的就是给它数据,它会显示在屏幕上,但并不知道数据的来源。如果您使用 NHibernate 之类的东西,您需要小心将实体直接传递到您的视图,因为您会遇到与延迟加载和 N + 1 查询相关的问题。视图模型通常是实体的精简版本。例如,如果您有一个具有 4 个属性的实体,但视图只需要消耗这些属性的 2/4,您将创建一个具有 2 个属性的单独视图模型,并使用像 Automapper 这样的映射库从您的实体映射到视图模型。

我可以将多个模型传递到剃须刀页面吗?例如,我如何列出 2 个不同的表?

这很简单。您创建一个顶级对象并为其提供 2 个属性来表示您要访问的实体。

public class MyViewModel
{
  public Entity1 FirstObject { get; set; }

  public Entity2 SecondObject { get; set; }
}

然后,您将创建一个强类型视图,并使用您在问题中发布的剃刀视图中使用的强类型视图助手渲染 FirstObject 和 SecondObject。@Html.TextBoxFor() 等

最后,您的控制器将接受 MyViewModel 作为参数,并根据您的视图中呈现的表单输入填充 FirstObject 和 SecondObject。

将所有 DAL 代码放在一个文件中更好吗?

您想将相关的 DAL 代码放在同一个文件中。事物通常由表格映射出来,但这一切都取决于您的对象之间的关系(例如,您的聚合根是什么)。您不想做的是盲目地为每个表实现一个存储库。您最终会得到一个真正程序化且贫乏的数据模型,该模型会通过对数据库的多次调用将对象图和关系拼接在一起。我建议研究领域驱动设计,以了解如何解决这个问题。

我只是在这里触及了表面。如果你想正确地做这些事情,你基本上需要学习最新的模式和实践。这是一个不同的运动。不像过去的文件、视图状态和 DataGrid 控件背后的单一代码的美好时光。那里有一些非常好的书,例如:

Brownfield 应用程序开发领域驱动设计 (Eric Evans) Clean Coder (Robert C Martin) 重构:改进现有代码的设计 (Martin Fowler) 企业应用程序架构模式 (Martin Fowler)

我并不是说要逐字阅读所有这些书籍,但我强烈推荐前 2 本书。我相信社区会对这些开发实践有更多的看法,但这是我对这一切的看法。谢谢,祝你好运。

于 2013-01-18T21:14:07.880 回答