我正在尝试使用不带EF的ASP.NET MVC,可能没有LINQ。首先,我在VS2010中的基本ASP.net mvc模板上创建了一个表/模型/控制器/视图(仅实现了索引页面和索引方法)。我目前正在尝试/错误,因为网络上的所有教程都基于EF,我有一个嵌入式c背景。
我的问题是:
架构是否正确?
我看到存储库模式用于一些开源项目,例如nearforums。它有什么优势以及它如何适应这一点,是否取代了DAL?
我应该将数据表传递给视图或表示数据表的对象吗?
我可以将多个模型传递给剃刀页面吗?例如,我如何列出2个不同的表?
将所有DAL代码放在一个文件中会更好吗?
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; }
}
}
ProductController.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);
}
........
........
}
Index.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>
}
答案 0 :(得分:3)
我看到存储库模式用于一些开源项目,例如nearforums。它有什么优势以及它如何适应这一点,是否取代了DAL?
存储库模式的好处是它允许您切换数据访问逻辑/ ORM。例如,如果您想从实体框架切换到NHibernate,您只需更新您在IoC容器内的注册,并且像魔术一样,您的代码使用NHibernate,并且知道您正在进行切换。它允许您的代码与底层持久性框架无关。据它所知,结果代码来自文件,Web服务调用或内存列表。如果必须从另一个组件进行相同的查询,您也可以重用。另一个好处是单元测试。使用当前的实现,您无法对控制器进行单元测试,因为它每次都会直接连接到您的数据库,因此根据定义将其作为集成测试。你肯定会想要利用ORM,或者你会一遍又一遍地编写相同的代码,直到它让你哭泣。设置/拆除连接,键入将所有原语转换为本机.NET类型等。如今处理本机ADO.NET已成为过去。让您的生活更轻松,并使用ORM。与此同时,强大的力量带来了巨大的责任。如果您不验证针对您的数据库生成和执行的查询,ORM可能是一场噩梦。如果使用不当,它们会产生性能问题。您将能够在大多数查询中使用LINQ,但有时您将不得不使用脏的本地原语并使用原始SQL。 ORM仍然可以处理这两种情况。
我应该将数据表传递给视图或表示数据表的对象吗?
您当然不想传递数据表。您希望将视图模型或实体传递给视图。视图应该对数据库一无所知。您所做的就是为其提供数据,并在屏幕上显示并不知道该数据的来源。如果你正在使用类似NHibernate的东西,你要小心将实体直接传递给你的视图,因为你遇到了与延迟加载和N + 1查询相关的问题。 View模型通常是您实体的精简版本。例如,如果您有一个具有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) 清洁编码器(罗伯特C马丁) 重构:改进现有代码的设计(Martin Fowler) 企业应用架构模式(Martin Fowler)
我并不是说逐字阅读所有这些书籍,但我强烈推荐前两本书。我相信社区对这些开发实践有更多的说法,但这是我对此的看法。谢谢,祝你好运。