如何在此方法中最小化数据库命中

时间:2016-10-14 00:34:36

标签: c# linq

在服务中我有一个方法,它从不同的表中收集数据并将其组合成一个单独的Dto accountDto

我最大的问题是不同的表上没有外键关系。因此,我必须建立自己的关系。

前两个方法GetAccountGetPerson只是通过Repository方法从单个表中获取数据。这两个表由一个共同的TrinId相关联。最后一个方法GetRoleDtos要复杂得多,涉及多个连接,如下所示。最后一位数据与AccountId相关联。

这种方法似乎多次袭击数据库。在遵循相同的服务/存储库模式的同时,如何最小化命中数并提高速度?

    public AccountDto GetAccountDto(int accountId)
    {
        try
        {
            Account account = _unitOfWork.AccountRepository.GetAccount(accountId);

            AccountDto accountDto = account == null ? new AccountDto() : new AccountDto
            {
                AccountId = account.AccountId,
                UserName = account.UserName,
                TrinId = account.TrinId,
                LastName = account.LastName,
                FirstName = account.FirstName
            };

            Person person = _unitOfWork.AccountRepository.GetPerson(accountDto.TrinId);

        accountDto.Person = person == null ? new PersonDto() : new PersonDto
        {
            Id = person.Id,
            TrinId = person.TrinId,
            AccountId = person.AccountId,
            LastName = person.LastName,
            FirstName = person.FirstName,
            MiddleName = person.MiddleName,
            Gender = person.Gender,
            BirthDate = person.BirthDate
        };

        accountDto.Roles = _unitOfWork.AccountRepository.GetRoleDtos(accountId).ToList();

        return accountDto;
    }
    catch (Exception ex)
    {
        Log.Error(ex);
        throw;
    }
}
public IQueryable<RoleDto> GetRoleDtos(int accountId)
    {
        var userModuleRoles = from account in _model.Accounts
                              join userRight in _model.UserRights on account.AccountId equals userRight.AccountId
                              join role in _model.Roles on userRight.RoleId equals role.Id
                              join organization in _model.Organizations on userRight.OrganizationId equals organization.Id
                              join module in _model.Modules on role.ModuleId equals module.Id
                              where (account.IsApproved == true && userRight.Status == 1 && account.AccountId == accountId)
                              select new RoleDto
                              {
                                  Id = role.Id,
                                  RoleName = role.Name,
                                  AccountId = account.AccountId,
                                  OrganizationId = organization.Id,
                                  OrganizationName = organization.Name,
                                  ModuleId = module.Id,
                                  ModuleName = module.Name
                              };

        return userModuleRoles;
    }

这是我在一个查询中的原始尝试。它有效,但我无法获得List<RoleDto>。我怎样才能获得角色Dto的列表?

我现在使用的查询显示在GetRoleDtos方法中,但它需要包含在此查询中。我确实有一个部分工作的解决方案,但现在删除了。我放弃了它,因为当没有RoleDto记录时,整个查询返回null。在这种情况下,我仍然需要一个填充的AccountDto,其中包含一个空的RoleDto集合。我相信我需要使用DefaultIfEmpty来获取和清空收集,但是在这一点上我放弃了,因为查询变得笨拙。 : - (

        return account;
    }

    public AccountDto GetAccountDto(int accountId)
    {
        return (from a in _model.Accounts
                       join p in _model.People on a.TrinId equals p.TrinId into perJoin
                       from per in perJoin.DefaultIfEmpty()
                       where a.AccountId == accountId
                       select new AccountDto
                       {
                           AccountId = a.AccountId,
                           UserName = a.UserName,
                           TrinId = a.TrinId,
                           LastName = a.LastName,
                           FirstName = a.FirstName,
                           Person = new PersonDto
                                {
                                    Id = per.Id,
                                    LastName = per.LastName,
                                    FirstName = per.FirstName,
                                    MiddleName = per.MiddleName,
                                    Gender = per.Gender,
                                    BirthDate = per.BirthDate
                                }
                       }).FirstOrDefault();
    }

1 个答案:

答案 0 :(得分:1)

我建议创建一个从您的存储库返回的新对象。这个新对象会是这样的,这只是一个不完整的想法:

public class AccountInfo {
    public int AccountId { get; set; }
    public string UserName { get; set; }
    public int TrinId { get; set; }
    public string LastName { get; set; }
    public string FirstName { get; set; }
    public Person PersonInfo { get; set; }
    public List<Roles> AccountRoles { get; set; }
}

然后在您的存储库中创建一个填充所有必要属性的方法,因为您可以基于Account清楚地获取List<Roles>accountId,然后加入您的基于TrinId的人信息。我会把查询留给你。