如何以正确的方式检索存储库模式中的关系数据?

时间:2015-05-27 05:22:00

标签: c# repository-pattern

我在“用户”表格中与部门,角色和团队有关系。

建议是在我通过存储库查询数据时,所以我更愿意返回“用户”模型,其中包含部门,角色和团队的填充完整对象和属性。

我目前的解决方案是使用服务层从相关存储库(UserService.cs)设置用户属性。

我的项目有服务层(服务),数据层(存储库)和域模型。

请参阅以下示例代码:

模型/ 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”

1 个答案:

答案 0 :(得分:1)

我认为您可以轻松识别当前方法的几个问题。   - 加载所有用户具有可怕的复杂性(SELECT N + 1,例如,对于您发出另一个O(n)查询的每个用户,给您O(n ^ 2)性能)   - 当您保存用户对象时,如果存储库也保存对部门等的更改,会发生什么?

我解决这个问题的方法是根据聚合根和值对象的概念对域进行建模,这两个概念都是域驱动设计的概念。你会发现很多资源,但exec摘要是聚合根具有全局标识,而且#34;拥有&#34;其聚合边界中的所有瞬态值对象。每个聚合根应该有一个存储库。

尝试避免聚合根之间的显式依赖关系(即,如果某个部门对您的应用程序有意义,请不要将Department属性添加到您的User对象)。聚合应该是独立的,并且依靠Ids相互依赖。修改单个聚合的操作应该封装在其中一个聚合对象上,而需要触及多个聚合根的操作(例如,将用户分配给新的部门)应该进入一个服务,该服务负责使用它们加载和修改两个聚合。库。