实体做得太多了?

Gie*_*ius 7 c# architecture dependencies linq-to-sql

我有一个旧的谜题,所以我想我会与你分享,可能会得到正确的方向.事实上,我们在数据库中的一些实体非常大(读取有很多属性),很少有业务逻辑使用所有实体属性,因此每次我需要考虑必须加载哪些属性才能使业务逻辑正常工作.非常假设的样本:

public class Product 
{
    public string Title {get;set;}
    public string Description {get;set;}

    public string RetailPrice {get;set;}
    public string SupplierId {get;set;}

    public Supplier Supplier { get;set;}

    // many other properties
}

public class ProductDiscountService
{
    public decimal Get(Product product)
    {
        // use only RetailPrice and Supplier code
        return discount;
    }
}

public class ProductDescriptionService 
{
    public string GetSearchResultHtml(Product product) 
    {
        // use only Title and Description
        return html;
    }
}
Run Code Online (Sandbox Code Playgroud)

看起来我可以提取接口IDiscountProduct和ISearchResultProduct,将产品标记为实现这些接口,然后创建实现每个接口的较小DTO,但是现在看起来有点矫枉过正(至少我没有看到有人使用接口对属性进行分组) .

将数据库中的实体拆分为较小的实体也看起来不合理,因为所有这些属性都属于产品,我担心我会被迫使用很多连接来选择某些东西,如果我决定某些属性属于另一个实体,这一举动将很难实施.

将特定方法的业务逻辑中使用的每个属性作为方法参数看起来也是不好的解决方案.

Evg*_*eni 1

除非属性很大(读取长字符串和/或二进制文件),否则我只会加载它们。

以下几点适用于简单属性(例如标题)

  1. 没有额外的代码(仅通过标题获取此产品,或仅通过价格获取,等等)
  2. 产品实例始终是完整的,因此您可以传递它而无需检查属性是否为空。
  3. 如果您必须延迟加载其他一些属性,那么它会比急切地加载它们花费更多。如果您有大约 20 个属性 - 这甚至不是一个大对象(同样,如果您的(假设的)描述属性的大小不是千字节)。

现在,如果您有相关对象(ProductSupplier) - 在我看来,这应该是延迟加载的,除非您知道将使用此属性。