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方法?
欢迎对此发表意见。
根据我的经验,我宁愿使用第一个。如果有一个更复杂的商业逻辑,那么肯定。通常我在复杂应用程序中有以下层:
- 查看剃刀页面
- 型号模型是数据传输对象,表示要显示的东西,而不是数据库中的
- 控制器控制器可以是轻量级的,只连接表示和业务逻辑
- 业务逻辑我更喜欢把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查询中执行,只能执行一些非常常见的调用(如一些字符串操作)。