You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#类层次结构下,如何实现DTO与领域对象的属性映射?

问题描述

简介

简单来说,假设领域层有3个类(我称之为业务对象BO),此处省略构造函数等内容,仅保留相关属性:

public class VehicleBo
{
    public string Manufacturer { get; set; }
}

public class CarBo : VehicleBo
{
    public int PassengerCount { get; set; }
}

public class TruckBo : VehicleBo
{
    public double MaximumLoad { get; set; }
    public bool HasTrailer { get; set; }
}

我们有一个DTO对象聚合了BO层次结构中的所有属性:

public class VehicleDto
{
    public string Manufacturer { get; set; }
    public int PassengerCount { get; set; }
    public double MaximumLoad { get; set; }
    public bool HasTrailer { get; set; }

    // 对应EF Core中VehicleBo映射数据库时定义的鉴别器
    public string VehicleType { get; set; }
}

我们使用Entity Framework Core将BO映射到关系数据库表,所有BO(VehicleBo、CarBo、TruckBo)共用一张Vehicles表,采用Table per hierarchy(TPH)(单表继承)策略存储。

背景逻辑

用户查看Vehicles表内容时看到的是VehicleDto数据,前端过滤排序请求会由一个小型框架处理,该框架通过属性名匹配将DTO属性映射到BO属性。

例如前端发送过滤请求(符号代码):

{
    Type: VehicleDto,
    Predicate: v => v.Manufacturer == "Ford"
}

框架会转换为:

{
    Type: VehicleBo,
    Predicate: v => v.Manufacturer == "Ford"
}

(注意此处类型为VehicleBo而非VehicleDto)并发送到后端。这种情况在属性名一致时可行,但像PassengerCount这类仅存在于子类CarBo的属性无法直接映射。

前端发送:

{
    Type: VehicleDto,
    Predicate: v => v.PassengerCount > 2
}

框架无法转换为v => v.PassengerCount > 2(因VehicleBo无该属性),实际需要转换为:

{
    Type: VehicleBo,
    Predicate: v => ((CarBo) v).PassengerCount > 2
}

EF Core可将其转换为SQL查询,这一逻辑可行。

问题挑战

我需要一种优雅的方式为框架提供DTO到BO的映射提示。最初考虑使用泛型属性,但C#不支持将表达式作为属性参数,只能使用字符串形式,这种方式繁琐且易出错。

请问有没有既优雅又简单且类型安全的解决方案?


内容的提问来源于stack exchange,提问作者Pavel Foltyn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 00:51:00