BLL (CRUD和业务对象)通常是如何构建的?

3
这与以下问题有关:什么是业务逻辑层中需要放置的内容?通过这个问题的答案(我还没有选择答案,因为可能还有其他人评论可以使它更清晰),我得出结论BLL将包括CRUD并根据需要访问DAL。
现在我的主要问题是BLL看起来像什么?例如,一个订单对象。对于CRUD,我看到一些实现具有像这样的OrderService,它是BLL的一部分:
public class OrderService
{
    public int CreateOrder(Order order)
    {
        ...
    }

    public int UpdateOrder(Order order)
    {
        ...
    }

    //... other code for CRUD
}

除了业务对象之外,这个问题还涉及到BLL中与业务对象相关的服务?

而在其他一些情况下,他们会这样做:

public class Order
{
    public int ID { get; set; }
    public decimal Amount { get; set; }
    //... etc.

    public int Create()
    {
        ...
    }

    public int Update()
    {
        ...
    }
}

但是将CRUD操作和属性结合在一起似乎有些不妥。
BLL(CRUD和业务对象)通常如何构建?
另外,由于数据通常来自UI输入,然后填充到业务对象中,那么我该如何验证数据?例如,对于订单和列表,我有Total属性,Total应等于OrderItem的总金额。在进行CreateOrder时,我该如何调用验证?我一直认为验证应该在实际属性设置器内完成。在进行CRUD操作期间,我该如何调用此操作?我是否应该在业务对象中实现一个Validate方法?
对此的任何意见都非常欢迎。

CRUD是我实际上与DAL相关联的术语。 - BCdotWEB
1个回答

2
根据我的经验,我更倾向于使用第一个。如果有更复杂的业务逻辑,那当然要用第二个。通常在一个复杂的应用程序中,我会有以下几个层次:
  • 视图。 Razor 页面
  • 模型。 模型是数据传输对象,表示要显示的内容,而不是来自数据库的内容。
  • 控制器。 控制器可以是轻量级的,只连接展示和业务逻辑。
  • 业务逻辑。 我更喜欢将 BL 放入一个单独的库(BLL)中。业务逻辑通过 DTO 与 MVC 控制器通信,并与数据层通信。
  • 数据层。 通过 EF 进行操作。
DTOs可以从多个数据库对象创建;如果您想隐藏某些细节,它们也可以是部分表示。在此问题中阅读更多信息。DTO还是一种很好的方式,可以迫使自己防止意外更新 - 或在此处查看。
在较小的应用程序中,控制器可以完成所有操作,因此不需要BLL。但是,在具有各种服务和方面的较大应用程序中,应使用BLL。有人会说BLL是模型的一部分 - 嗯,有点是,但它不仅仅是填充视图的东西。
让我再次强调:不要用加农炮打麻雀...简单的任务需要简单的解决方案。
补充
您可以使用选择器表达式将数据库实体映射到DTO实体。一个例子在这里,下面我假设数据库中有一个Kitten表格,再给出另一个例子。
Class KittenDto {
    public static Expression<Func<Db.Kitten, KittenDto>> = (kitten) => return new KittenDto() {
        Id = Id,
        Name = Name,
        CustomDataNotInDb = 42
    };
    public int Id;
    public string Name;
    public int CustomDataNotInDb;
}

然后你可以使用:
var kittenDto = context.Kittens
    .Single(k => k.Id == givenId)
    .Select(KittenDto.Selector);

注意,如果Selector不是Expression<>,则它会在本地执行。如果它是一个Expression,那么它将被转换为一个查询,并且数据库将完成其余的工作。从数据库返回的结果将是一个KittenDto对象(或更准确地说:它将只有所请求的属性,没有其他内容)。
此外,请注意编写复杂表达式可能会很困难——或者至少在我上次使用.NET 4.5时是这样的。例如,在DB查询中无法执行函数调用,只能执行一些非常常见的操作(如一些字符串操作)。

谢谢回复。我已经阅读并选择了第一个选项。我想问一下,在您的设置中,您是如何传递数据的?目前,在我的业务逻辑中,我也有单独文件夹中的业务实体。当业务层调用DAL时,我会将业务实体转换为DAL中的POCO(作为DTO)。您能否就此发表评论? - g_b
我已将插件放入问题中。通常情况下,每当要将DTO对象发送到视图时,我都会使用它们进行工作。但是,在BLL内部操作中,有时我仅使用EF对象而不进行映射。 - Gábor Imre

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接