c# - 如何以正确的方式在存储库模式中检索具有关系的数据?

标签 c# repository-pattern

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

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

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

Repository/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) 性能) - 保存用户对象时会发生什么,存储库是否也应保存对部门等的更改?

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

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

关于c# - 如何以正确的方式在存储库模式中检索具有关系的数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30473779/

相关文章:

c# - 一个 DbContext Instance 跨越多个 Repositories

c# - 如何在 Startup.cs 文件的 ConfigureServices 方法的 AddJwtBearer 选项中设置动态 IssuerSigningKey 和 TokenDecryptionKey

c# - 已执行 SQL 更新命令但未更改数据库

c# - Entity Framework - 使用数据注释的属性的默认值

c# - 如何在C#中释放一个通信端口(RS-232 COM端口)

c# - 带有 Dapper 的 .net 核心的通用存储库模式

c# - 设置鼠标悬停/用户单击按钮的样式

web-services - 如何在 DDD 中处理外部有状态的 Web 服务?

c# - 工作单元 + 存储库模式 : The Fall of the Business Transaction Concept

oop - 面向对象的设计