这与这个问题有关:
What to put in Business Logic Layer?
在这个问题的答案中(尚未选择答案,因为可能有其他人愿意评论以使我更清楚),我得出的结论是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
}
除了Business对象外,我还有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输入,然后填充到Business对象,我将如何验证数据?例如,我有订单和列表的属性总计,总计应该等于OrderItem的总金额。在说CreateOrder时,我将如何调用验证?我一直认为验证应该在实际的属性设置器中完成。如何在CRUD期间调用它?我是否应该在Business Object中实现Validate方法?
对此的任何意见都非常受欢迎。
答案 0 :(得分:1)
根据我的经验,我宁愿使用第一个。如果有一个更复杂的业务逻辑,那么肯定。通常我在复杂应用程序中有以下图层:
可以从多个DB对象创建DTO;如果你想隐藏一些细节,它们也可以是部分表示。阅读更多in this question。 DTO也是强迫自己阻止unintended updates - 或查看here的好方法。
在控制器可以执行所有操作的较小应用程序中不需要BLL。但是在具有各种服务和方面的大型应用程序中,您应该使用它。有人会说BLL是模型的一部分 - 嗯,有些是,但它远远超过填充视图的东西。
让我再次强调:不要使用大炮射麻雀......简单的任务需要简单的解决方案。
ADD-ON
您可以通过选择器表达式将数据库实体映射到DTO实体。一个例子是here,假设数据库中有一个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将完成其余的工作。数据库的结果将是一个KittenDto
对象(或更确切地说:它只有所请求的属性,仅此而已)。
还要注意编写复杂的表达式可能很困难 - 或者是我上次在.NET 4.5中使用它时。例如,函数调用不能在DB查询中执行,只能执行一些非常常见的函数调用(如某些字符串操作)。