单一负责原则和对实体的LINQ

时间:2018-06-23 22:16:10

标签: c# linq-to-entities single-responsibility-principle

即我有以下模型:

public class CompanyDto
{
    public int ID { get; set; }
    public string Name { get; set; }
    public string CompanyLogo { get; set; }
    public string EmailUser { get; set; }
    public int UserCount { get; set; }
}

和某个存储库类中的某些方法,该方法从Db中选择数据并将其推送到域DTO类:

public List<CompanyDto> CompanyList()
{
    var list = (from i in _db.Companies
                select new CompanyDto()
                {
                    ID = i.Id,
                    CompanyLogo = i.CompanyLogo,
                    Name = i.Name,
                    UserCount = i.Users.Count,
                    EmailUser = i.UserDetail.Email
                }).ToList();

    return list;
}

我们可以看到,我们的BL模型需要从3个实体(表)中获取合并数据:公司,UserDetail和Users中的用户数

它正常工作。但是我想到了SRP。这个原则说,那应该是改变阶级的唯一原因之一。但是在我们的案例中,我们有两个更改班级的理由:

  1. 更改数据库实体的结构
  2. 更改DTO类别

此代码是否违反SRP?

1 个答案:

答案 0 :(得分:1)

  

此代码是否违反了SRP?

是的。但是不用担心。

我相信您的问题可能会在Code review得到更好的解决。

IMO,您说得很对,但是我所看到的是很普遍的,并且会经历我所知道的所有代码审查。
目前,我看不到将代码重写为两部分(都具有自己的SRP)的方法,因为您要描述的是两个数据载体之间的 mapping 。 (嗯,我看到了通过创建一个中间类来学习的方法,但这将是多余的IMO)

可以做什么;是将映射[数据库实体Company-> DTO CompanyDTO]移动到另一个位置。然后,此位置(在此作为扩展方法实现)负责从数据库实体到DTO的所有映射。

public static class CompanyExtensions{
    public static CompanyDto ToDto( this Company me ){
        return new CompanyDto{
            ID = me.Id, 
            ...the rest of the fields.
        }
    }
}

将这样称呼:

public List<CompanyDto> CompanyList()
{
    var result = (from company in _db.Companies
        select company.ToDto());
    return result.ToList();
}

使用扩展方法而不是CompanyDto中的方法的原因是,您不希望数据库实体从DAL中泄漏出来。
使用扩展方法而不是帮助程序类的原因是您获得了智能感知。