假设我有一个包含员工和部门的数据库。我创建了一个简单的对象模型来处理这个问题:
class Employee
{
decimal Salary;
Department Department;
}
class Department
{
decimal TotalSalaries; //calculated as the sum of all employees salaries
//stored in database, not just a C# property
}
还有..
class Employees
{
void Create(Employee e);
void Update(Employee e);
void Delete(Employee e);
...
}
class Departments
{
...
}
如果我想更新一个员工,我会简单地做:
Employee emp = Employees.GetById(1);
emp.Salary += 100; //salary increase
Employees.Update(emp);
我希望每次更新其中一名员工的 Salary
时自动重新计算 Department
的 TotalSalaries
我可以做以下事情:
void Update(Employee e)
{
... //
... // sql stuff to update employee fields.
Departments.ReCalculateTotalSalaries(e.Department.Id);
}
但如果我这样做,我认为我违反了单一职责原则。为什么员工更新方法应该关心 Departments
?这是一个非常简单的示例,但如果我在实体之间有很多依赖关系,代码可能会变得非常困惑。
我已经考虑过其他方法来做到这一点:
1) 为 Employee 创建一个服务类:EmployeeService
。然后在这个类中,定义一个方法 Update()
来更新一个员工。该方法将更新员工并重新计算部门总数(当然是通过调用存储库方法)。
void Update(Employee e)
{
Employees.Update(e);
Departments.ReCalculateTotalSalaries(e.Department.Id);
}
问题:如果我的数据模型中有很多依赖项,我几乎必须“加倍”我的模型层(类数 x2)。另外:我如何确定 Controller (或 View )将始终调用服务方法,而不是直接调用存储库?
2) Employees
存储库中有一个事件 OnSalaryChange()
,从 Update()
方法调用。存储库 Departments
将订阅它并在需要时执行必要的操作(换句话说:调用 ReCalculateTotalSalaries()
)。然后,属于Departments
的内容留在Departments
中,Employees
存储库不必关心其他实体。
问题:当薪水发生变化时(如果有多个订阅者),可能很难(通过阅读代码或在 Debug模式下)了解发生了什么。如果需要按特定顺序调用订阅者,这也可能成为问题。
最佳答案
您应该有理由在数据库中使用计算字段(性能?)。 我尽量避免这种情况。
因为更新不是唯一的情况:如果您删除了一个 Employee,您也必须重新计算。
但这可能很危险(出于一个原因,有一天您在数据库中使用脚本工作,却忘记在更新员工的薪水后手动更新部门表?)
所以
您可以在您的数据库中创建一个触发器(如果您先有代码,您始终可以使用 SMO 来保持“代码”逻辑)
您可以创建数据库 View
您可以在您的 Department 实体中拥有一个 Employees ICollection(或 IList,或...),并以“简单获取属性”的形式获得总薪水,它对列表的薪水求和...
关于c# - 存储库模式以及如何管理实体之间的依赖关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10114264/