如果我想从数据库中显示数据,我应该在BLL项目类中创建与DAL项目中的poco类相同的poco类,并将其返回到UI项目

本文关键字:项目 poco UI DAL 返回 创建 数据 显示 数据库 我应该 如果 | 更新日期: 2023-09-27 18:09:03

我有一个架构问题。我有DAL项目与poco类(数据库中的等效表),BLL项目和UI项目。UI项目参考了BLL项目,BLL项目参考了DAL项目。

我想显示在UI项目数据,例如从表产品从数据库。我是否应该在BLL项目类中创建与DAL项目中的poco类相同的类,并将其返回到UI项目并显示它?

所以这是我在DAL中的poco类(数据库中的等效表):

public class Product 
{
    public int  ID  {get; set; }
    public string  Name   {get; set; }
    public String  Address {get; set; }
}

在BLL中,我创建了与上面的poco类相同的业务对象:

public class ProductBO
{
    public int ID { get; set; }
    public string Name { get; set; }
    public String Address { get; set; }
}

在BLL中,我也有从DAL获取产品并将其映射到业务对象的方法- ProductBO:

public class ProductService
{
    public List<ProductBO> GetAllProducts()
    {
        List<ProductBO> productsBO = new List<ProductBO>();
        using (var context = NorthwindFactory.CreateContext())
        {
            List<Product> products = context.Product.ToList();
            foreach (var product in products)
            {
                productsBO.Add(new ProductBO { ID = product.ID, Address = product.Address, Name = product.Name });
            }
        }
        return productsBO;
    }
}

现在在控制器的UI项目中,我从BLL调用服务,它返回列表,在视图中,我可以使用业务对象ProductBO显示数据。

@model IEnumerable<WebApplication1.BLL.BusinessObjects.ProductBO>
<table class="table">
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.Name)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Address)
        </th>
    </tr>
@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Name)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Address)
        </td>
    </tr>
}
</table>

是正确的架构方法吗?

如果我想从数据库中显示数据,我应该在BLL项目类中创建与DAL项目中的poco类相同的poco类,并将其返回到UI项目

嗯,没有唯一正确的方法。但是我倾向于避免创建一组DAL类。现代orm允许使用POCO类。是的,有一些限制(如枚举),但我认为不值得为每个业务实体创建两个副本并在它们之间进行映射。因此,我使用位于业务逻辑组装中的单个POCO实体。实体框架与实体一起工作,保存并从数据库加载它。没有映射。

表示层不同。通常,同一实体在不同的页面上有几种表示形式。你也会使用不同的Data Annotation属性来设置视图模型上的限制,或者一些UIHints。这会用特定于ui的逻辑污染您的业务实体。此外,您还经常需要显示格式化或修改的数据,例如Person实体的FullName而不是FirstName和LastName。因此,这里我不使用POCO业务实体,而是创建视图模型。

对于您的产品示例,此方法看起来像:

  • 业务逻辑组件具有POCO实体Product
  • 持久性程序集引用业务逻辑程序集并使用相同的Product
  • UI项目有不同的视图模型ProductViewModel, BriefProductViewModel等。它还负责Product和视图模型之间的映射。注意:手工映射费时。我建议你使用一些映射库,如AutoMapper或valueinjector

您应该在BLL项目中定义您的POCO(域)对象,因为它们是业务对象。

你的DAL应该有一个对BLL的引用,而不是相反。

就我个人而言,我是洋葱架构的追随者,它将您的域置于应用程序的中心。你添加的任何层都应该只向内引用,而不是向外。所以根据这个定义,你的BLL是中心,不引用任何东西。添加一个DAL层,它只能向内引用,所以它可以引用BLL。UI层也只引用BLL,而不引用DAL,因为DAL是一个实现细节。