实体做得太多

本文关键字:太多 实体 | 更新日期: 2023-09-27 18:35:46

我有一个老拼图,所以我想我会和你分享,也许会得到正确的方向。问题是,我们在数据库中的一些实体非常大(读取有很多属性),并且业务逻辑很少使用所有实体属性,因此每次我都需要考虑必须加载哪些属性才能使业务逻辑正常工作。非常假设的样本:

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

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

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

将特定方法的业务逻辑中的每个属性用作方法参数看起来也是糟糕的解决方案。

实体做得太多

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

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

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

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