我有一个域名,员工可以在其中拥有角色列表。还有一个新的角色添加功能..在添加新角色时,我们需要检查员工是否已经具有“VP”角色。如果它已经存在,则不应添加新角色。此逻辑需要存在于Employee Domain实体中。
我通过添加方法名IsNewRoleAllowed()
来启动它,它将返回一个布尔值。如果是,则业务层将新角色插入数据库。
但为了更自然OO
,我决定通过创建一个函数AddRole
来改变Employee对象的责任。它将执行角色添加责任,而不是返回布尔值。
我通过接收Action<int, int>
作为参数来实现上述目标。它工作正常。
问题
将DAL方法传递给实体是否正确?
更新
@ThomasWeller补充了我同意的重要观点......
有角色是BL的纯粹概念。它与DAL无关。
- 醇>
在这种方法中,BL将具有驻留在DAL中的代码的依赖性。它(BL)甚至应该在DAL实际上不存在时起作用。
但是,由于我没有使用ORM,我如何修改代码以像建议的方法一样工作?
参考
CODE
域实体
public class Employee
{
public int EmployeeID { get; set; }
public string EmployeeName { get; set; }
public List<Role> Roles { get; set; }
//Add Role to Employee
public int AddRole(Role role, Action<int, int> insertMethod)
{
if (!Roles.Any(r => r.RoleName == "VP"))
{
insertMethod(this.EmployeeID, role.RoleID);
return 0;
}
else
{
return -101;
}
}
//IDataRecord Provides access to the column values within each row for a DataReader
//IDataRecord is implemented by .NET Framework data providers that access relational databases.
//Factory Method
public static Employee EmployeeFactory(IDataRecord record)
{
var employee = new Employee
{
EmployeeID = (int)record[0],
EmployeeName = (string)record[1],
Roles = new List<Role>()
};
employee.Roles.Add(new Role { RoleID = (int)record[2], RoleName = (string)record[3] });
return employee;
}
}
BusinessLayer.Manager
public class EmployeeBL
{
public List<Employee> GetEmployeeList()
{
List<Employee> employees = EmployeeRepositoryDAL.GetEmployees();
return employees;
}
public void AddRoleToEmployee(Employee emp, Role role)
{
//Don't trust the incoming Employee object. Use only id from it
Employee employee = EmployeeRepositoryDAL.GetEmployeeByID(emp.EmployeeID);
employee.AddRole<Employee>(role, EmployeeRepositoryDAL.InsertEmployeeRole);
//EmployeeRepositoryDAL.InsertEmployeeRole(emp.EmployeeID, role.RoleID);
}
}
DAL
public static void InsertEmployeeRole(int empID, int roleID)
{
string commandText = @"INSERT INTO dbo.EmployeeRole VALUES (@empID, @roleID)";
List<SqlParameter> commandParameters = new List<SqlParameter>()
{
new SqlParameter {ParameterName = "@empID",
Value = empID,
SqlDbType = SqlDbType.Int},
new SqlParameter {ParameterName = "@roleID",
Value = roleID,
SqlDbType = SqlDbType.Int}
};
CommonDAL.ExecuteNonQuery(commandText, commandParameters);
}
答案 0 :(得分:1)
没有。拥有角色首先是BL的纯粹概念,它与DAL无关。此外,在您的方法中,BL将具有驻留在DAL中的代码的依赖性,这将是错误的方向。 BL应该是持久性不可知(即它不应该以任何方式依赖于DAL中会发生的事情 - 它甚至应该在DAL实际上不存在的情况下工作。)。此外,DAL的职责只是持久化对象 - 而不是处理驻留在内存中的任何集合。
尽量保持简单,只需:
public int AddRole(Role role)
{
if (!Roles.Any(r => r.RoleName == "VP"))
{
Roles.Add(role.RoleName);
return 0;
}
else
{
return -101;
}
}
...在你的Employee
课程中,让DAL处理所有与持久性相关的问题(如果使用ORM,它会进行级联更新)。
答案 1 :(得分:1)
将DAL方法传递给实体是否正确?
我避免将DAL逻辑注入我的域模型。
更新域实体(例如Employee
)后,无需更新数据库。
常见的解决方案是:
为了跟踪新的/脏/已删除的实体Unit of Work模式
通常使用
: