如何以正确的方式检索库模式中有关系的数据
本文关键字:模式 数据 有关系 检索 方式 | 更新日期: 2023-09-27 17:50:57
我的"User"表中有与部门、角色和团队相关的关系。
建议当我在存储库上查询数据时,所以我更喜欢返回"User"模型,其中包含完整的对象和Department, Role和Team的属性。
我目前的解决方案是使用服务层从相关的存储库(UserService.cs)设置用户属性。
我的项目有服务层(Service),数据层(Repository)和领域模型。
请参见下面的示例代码:
模型/User.cs
public class User{
public string username { get; set; }
public string firstname { get; set; }
public string surname { get; set; }
public Int32 DepartmentId { get; set; }
public Department Department { get; set; }
public Int32 RoleId { get; set; }
public Role Role { get; set; }
public IList<Team> Teams { get; set; }
}
库/UserRepository.cs
public class UserRepository : IUserRepository{
private sqlSelectStatement = String.Format(@"SELECT u.[Id]
,[UserName]
,[FirstName]
,[LastName]
,[Email]
,[Telephone]
,[DepartmentId]
,[TeamId]
,[RoleId]
,[Enabled]
,[Created]
,[Modified]
,[UpdatedBy]
FROM {0}[User] ", SchemaOwner);
public IEnumerable<User> GetAll()
{
var dbcommand = this.SessionContext.GetSqlCommand(sqlSelectStatement );
return this.SessionContext.GetList<User>(dbcommand);
}
}
服务/UserService.cs
public class UserService : IUserService
{
private IUserRepository userRepository;
private ITeamRepository teamRepository;
private IDepartmentRepository departmentRepository;
private IRoleRepository roleRepository;
public IEnumerable<User> GetAll()
{
var users = userRepository.GetAll();
var departments = departmentRepository.GetAll();
var teamMembers = teamMemberRepository.GetAll();
var roles= roleRepository.GetAll();
foreach (User user in users){
user.Department = departments.Where(department=>department.Id== user.departmentId);
user.Role = roles.Where(role=>role.Id== user.roleId);
user.Teams = teams.where(team=>team.UserId == user.Id);
}
}
}
请注意,我没有使用任何"ORM"框架,也没有计划使用任何"ORM"
我认为您可以很容易地识别当前方法的几个问题。加载所有用户非常复杂(SELECT N+1,例如,对于每个用户,你发出另一个O(N)查询,给你O(N ^2)的性能)-当您保存用户对象时,存储库是否也应该保存对部门等的更改?
我解决这个问题的方法是根据聚合根和值对象的概念对你的领域建模,这两个概念都是领域驱动设计的概念。您可以找到很多关于这方面的资源,但执行总结是,聚合根具有全局标识,并且"拥有"其聚合边界中的所有瞬时值对象。每个聚合根应该有一个存储库。尝试避免在聚合根之间显式依赖(即,如果一个部门对你的应用程序有意义,不要在你的User对象中添加department属性)。聚合应该是自包含的,并且通过id相互依赖。修改单个聚合的操作应该封装在一个聚合对象上,而需要触及多个聚合根的操作(例如,将用户分配给新部门)应该进入一个服务,该服务负责使用它们的存储库加载和修改两个聚合。