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

本文关键字:结构化 CRUD 业务 对象 BLL | 更新日期: 2023-09-27 18:28:02

这与这个问题有关:

在业务逻辑层中放入什么?

有了这个问题的答案(还没有选择答案,因为可能有其他人愿意评论,让我更清楚),我得出的结论是,BLL将包括CRUD,并将根据需要访问DAL。

我现在的主要问题是我的BLL是什么样子的?例如,一个Order对象。对于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输入,然后填充到业务对象中,我将如何验证数据?例如,我有order和List的属性Total,Total应该等于OrderItem的总金额。当执行CreateOrder时,我将如何调用验证?我一直认为验证应该在实际的属性设置器中进行。在CRUD期间,我将如何调用它?我是否也应该在业务对象中实现Validate方法?

欢迎对此发表意见。

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

根据我的经验,我宁愿使用第一个。如果有一个更复杂的商业逻辑,那么肯定。通常我在复杂应用程序中有以下层:

  • 查看剃刀页面
  • 型号模型是数据传输对象,表示要显示的东西,而不是数据库中的
  • 控制器控制器可以是轻量级的,只连接表示和业务逻辑
  • 业务逻辑我更喜欢把BL放在一个单独的库(BLL)中。业务逻辑与MVC控制器(通过DTO)和数据层进行通信
  • 数据层通过EF进行操作

DTO可以从几个DB对象中创建;如果你想隐藏一些细节,它们也可以是部分表示。阅读此问题中的更多内容。DTO也是迫使自己防止意外更新的好方法——或者参见此处。

在控制器可以做所有事情的较小应用中不需要BLL。但在有各种服务和方面的大型应用程序中,你应该使用它。有些人会说BLL是模型的一部分——嗯,有点是的,但它远不止是填充视图的东西。

让我再次强调:不要用大炮射麻雀。。。简单的任务需要简单的解决方案。

附加

您可以通过选择器表达式将DB实体映射到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,那么它将被转换为一个查询,DB将完成其余的工作。DB的结果将是一个KittenDto对象(或者更准确地说:它将只具有请求的属性,没有其他属性)。

还要注意,编写复杂的表达式可能很困难——或者我上次在.NET4.5中使用它时也是如此。例如,函数调用不能在DB查询中执行,只能执行一些非常常见的调用(如一些字符串操作)。