【问题标题】:How to retrieve data with relation in Repository Pattern in the right way?如何以正确的方式在存储库模式中检索具有关系的数据?
【发布时间】:2015-08-09 00:38:01
【问题描述】:

我的“用户”表中有与部门、角色和团队相关的关系。

建议是当我通过存储库查询数据时,因此我更喜欢返回“用户”模型,并为部门、角色和团队填充完整的对象和属性。

我目前的解决方案是使用服务层从相关存储库(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”

【问题讨论】:

    标签: c# repository-pattern


    【解决方案1】:

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

    我解决这个问题的方法是根据聚合根和值对象的概念对您的域进行建模,这两个都是域驱动设计的概念。您会为此找到大量资源,但执行摘要是聚合根具有全局标识并“拥有”其聚合边界中的所有瞬态值对象。每个聚合根应该有一个存储库。

    尝试避免聚合根之间的显式依赖(即,如果部门对您的应用程序有意义,则不要将部门属性添加到您的用户对象)。聚合应该是自包含的,并且通过 Ids 相互依赖。修改单个聚合的操作应封装在其中一个 Aggregate 对象上,而需要涉及多个聚合根的操作(例如,将用户分配给新部门)应进入负责使用其加载和修改两个聚合的服务。存储库。

    【讨论】:

      猜你喜欢
      • 2020-03-25
      • 1970-01-01
      • 2018-04-28
      • 2018-04-02
      • 1970-01-01
      • 1970-01-01
      • 2015-12-31
      • 1970-01-01
      • 2021-10-06
      相关资源
      最近更新 更多