【问题标题】:Where do derived or inferred properties belong in an application?派生或推断的属性在应用程序中属于哪里?
【发布时间】:2026-01-15 19:10:01
【问题描述】:

我首先使用代码构建应用程序并生成数据库。

我不能再修改数据库,所以我不能添加/更改列和表。但是域模型(不确定我是否正确使用了该术语)需要可以从数据库数据中推断出但不明确存在的新属性(属于域的一部分)。

我的数据库存储房屋的销售信息。所以我有两张桌子,Houses 和 Sales。这些表由houseID 关联。现在我希望房屋有一个名为LastSaleDate 的属性,但我无法更改底层数据库。

那么,我将如何正确构建这个新属性并将其添加到适当的层中?这是我的 poco/entities 的样子。只是伪编码...

[我正在尽我所能了解我使用的工具和方法。我的所有假设都可能完全错误,也许我要把它添加到我的 pocos 中。如果是这种情况,请解释它是如何工作的]

[Table("HOUSE_TABLE")]
public class house {
 //some properties
public int HouseID {get;set;}
}

[Table("SALE_TABLE")
public class sale {
 //some properties
 public int HouseID {get;set;
 public int SaleID {get;set;}
 public datetime SaleDate {get;set;}
 public virtual House House {get;set;}
}

我几乎觉得这会创建 2 个级别的映射。不过,我不相信我曾在网上看到的任何代码中看到过这种情况。

poco -> AutoMapper?? -> entities -> Automapper -> viewModels

【问题讨论】:

    标签: c# entity-framework domain-driven-design automapper methodology


    【解决方案1】:

    这个逻辑很可能属于实体。实体应该既有数据又有行为。您似乎在描述的是一些作为属性公开的行为。因此,您应该为您的实体添加派生值的属性。默认情况下,如果属性只有一个 getter,则 EF 不会尝试将值映射到数据库。

    例如:

    [Table("HOUSE_TABLE")]
    public class house 
    {
        //some properties
        public int HouseID {get;set;}
    
        public virtual ICollection<Sale> Sales { get; set; }
    
        public DateTime LastSaleDate 
        {
            get 
            {
                return this.Sales.OrderByDescending(s => s.SaleDate).First();
            }
        }
    }
    

    【讨论】:

    • 上述对象是我定义的实体吗?
    • 如何在表达式中使用这些属性?当我尝试使用基于推断属性的谓词生成器添加表达式时,现在出现运行时错误。
    • 使用代码优先,如果您的集合Sales 是虚拟的,它将被延迟加载。然后,您应该可以使用任何表达式。