我应该在BLL项目类中创建像DAL项目中的poco类一样,如果我想显示数据库中的数据,还是将它返回到UI项目?

时间:2014-06-18 10:57:51

标签: c# asp.net-mvc entity-framework architecture

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

我想在UI项目数据中显示例如来自数据库的表Product。 我应该在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调用服务返回List,在视图中我可以使用业务对象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>

架构方法是否正确?

2 个答案:

答案 0 :(得分:1)

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

您的DAL应该引用BLL,而不是相反。

就个人而言,我是Onion architecture的关注者,它将您的域名置于应用程序的中心。您添加的任何图层应仅向内引用,而不向外引用。因此,根据该定义,您的BLL是中心,并没有引用任何内容。添加DAL图层,它只能向内引用,因此它可以引用BLL。 UI层也仅引用BLL,但不引用DAL,因为DAL是实现细节。

答案 1 :(得分:1)

嗯,没有单一正确方法。但我倾向于避免创建一组DAL类。现代ORM允许使用POCO课程。是的,有一些限制(如枚举),但恕我直言,它不值得创建每个业务实体的两个副本和它们之间的映射。所以,我选择了位于业务逻辑组件中的单个POCO实体。实体框架与该实体一起保存并从数据库加载它。没有映射。

表示层不同。通常,您在不同页面上有多个相同实体的表示。您还将使用不同的Data Annotation属性来设置视图模型或某些UIHints的限制。这将使用特定于UI的逻辑污染您的业务实体。您还经常需要显示格式化或修改过的数据,例如FullName而不是Person实体的FirstName和LastName。所以,在这里我不会使用我的POCO业务实体,而是创建视图模型。

使用您的产品样本,此方法将如下所示:

  • 业务逻辑程序集具有POCO实体Product
  • 持久性程序集引用业务逻辑程序集并使用相同的Product
  • UI项目具有不同的视图模型ProductViewModelBriefProductViewModel等。它还负责Product和视图模型之间的映射。注 - 手动映射非常耗时。我建议你使用一些映射库,比如AutoMapper或ValueInjecter