单一职责原则和 LINQ to Entities

Single Responsible Principle and LINQ to Entities

即我有以下型号:

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; }
}

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

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 个实体(表)中获取组合数据:Company、UserDetail 和来自 Users 的用户数

它工作正常。但我考虑 SRP。这个原则说,这应该是一个而且唯一一个改变的理由 class。但在我们的例子中,我们有两个理由来改变 class:

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

此代码是否违反 SRP?

Does this code violate SRP ?

是的。不过别担心。

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

IMO 你说得很对,但我看到的很常见,并且会通过我所知道的所有代码审查。
目前,我看不出有什么方法可以将您的代码重写为 2 个部分 [都具有自己的 SRP],因为您所描述的是两个数据载体之间的 映射 。 (好吧,我通过创建一个中间 class 看到了一个,但这在我看来是多余的)

可以做什么;就是将映射[数据库实体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
使用扩展方法而不是帮助程序的原因 class 是因为您可以获得智能感知。