我有一个c#
WebApi
项目,该项目使用Dapper
和Repository Pattern
作为数据层。
在其他项目中,我按业务逻辑模块创建了存储库。因此,与其创建每个实体的存储库,不如创建一个可以在内部引用多个实体的存储库,因为并非所有实体或数据库表都具有更新,删除和插入。
例如,我曾经有EmployeeRepository
,并且在该存储库中,我将处理与员工相关的任何事情,因此在该存储库中,我可以处理许多与员工相关的表。
我的SQL
数据库大约有350个表,但是在这个项目中,我只是怀疑如果正确的方法是为每个表或实体都有一个存储库,每个表或实体都有自己的Add,Get,删除,更新,删除等
在EmployeeRepository
示例中考虑以上内容,如果我要处理的员工数据管理工作可以说5张表:
然后我将有5个存储库,这样:
如果上面的方法是正确的方法,那么是否有任何插件可以为您生成Entity模型类,所以您不必一个个地手工制作?
什么是最佳实践模式?
答案 0 :(得分:2)
我认为没有最佳实践。它更受项目的实际需求以及如何使用这些存储库的驱动。
如果您有350个表,我个人会尝试将它们分组到更大的逻辑存储库中。表结构可能会发生变化,但背后的逻辑仍然存在:您想管理员工人数,而将员工人数数据存储在1个,2个或10个表中则无关紧要。仅出于争论的目的,想象一下您必须移至对象数据库,而所有employyee数据现在都只是一个文档。如果您想保持业务层不变,那么您所有的“表”存储库都必须访问一个文档。
对我来说,指导原则是“什么是我的主要实体,什么是我的从属实体”。如果没有员工,假期或休假是不存在的,所以我可以想象一个Empolyee存储库,上面写着:
GetEmployee(employeeId)
GetEmployeeHoliday(employeeId)
GetEmployeeLeave(employeeId)
从属实体的ID在这里并不重要,因此单独的存储库可能会过大。
如果您决定使用350个存储库,那么我至少会考虑将为您提供通用GetById,Save,Find等方法的通用存储库基类。仅扩展具有更多逻辑的存储库。我认为不超过50,而从第一种方法开始,它们或多或少就是您的“主要实体”。
无论如何,恕我直言,最终取决于您,您的个人喜好和项目需求。
答案 1 :(得分:0)
对我来说,更重要的是,业务层不应该直接与实体合作。取而代之的是,BL使用域或某种DTO,然后将其传递到处理该类型的存储库,该存储库显示“嘿,为我保存”。然后,存储库本身接受BL知道的该域/ dto项,然后将其转换为要用于持久化它的任何实体/技术(EF / Dapper)。将来,如果您需要将其发送给WebApi呼叫,则可以在此处进行更改,而无需担心。但是显然,由于它对业务类型实体做出了反应,所以最终您几乎得到了业务存储库,但我认为它提供了最大的灵活性。
编辑:示例:
public class EmployeeBL
{
private readonly ICreateEmployeeRepository _repo...
public IResult CreateEmployee(CreateEmployeeRequestDto dto)
{
// Business Logic here
EmployeeCreateDomainState request = ... Mapped from dto/business logic
var rowsAffected = _repo.Execute(item);
...
}
}
public class CreateEmployeeRepository : ICreateEmployeeRepository
{
public CreateEmployeeRepository (IoC inect stuff)...
public int Execite(EmployeeCreateDomainState request)
{
using (var empCtx = EmpDbContextFactory.Create())
{
var employeeEntity = ... // Map from request
var employeeAddressEntity = ... // Map from request
empCtx.Employees.Add(employeeEntity);
empCtx.EmployeeAddresses.Add(employeeAddressEntity );
return empCtx.SaveChanges();
}
}
}
当然,也许您需要访问多个数据库或其他任何东西,并且可以在此处内部完成所有操作。
您还可以拥有一个通用存储库,例如:
IRepository