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

ASP.NET Core MVC中如何对继承自抽象类的Product对象实现安全筛选?

解决方案

以下方案从改造成本由低到高排列,可根据项目实际情况选择:


方案1:模式匹配快速实现(无需修改现有实体结构)

直接使用C#原生类型模式匹配,无反射性能损耗,代码简洁,EF Core也可正常解析为SQL语句:

// 筛选重量大于5kg的商品,自动过滤无Weight属性的类型
var filteredProducts = products
    .Where(p => p is ProductB b && b.Weight > 5)
    .ToList();

// 如需直接拿到匹配类型的集合,可使用OfType
var matchedProductB = products.OfType<ProductB>().Where(b => b.Weight >5).ToList();

缺点:如果后续新增其他带Weight属性的商品子类,需要同步修改筛选条件的匹配逻辑。


方案2:提取公共属性接口(推荐,可维护性最高)

针对跨子类的通用属性,抽离独立接口标记对应类型,后续新增商品无需修改已有筛选逻辑:

  1. 定义属性接口
public interface IHasWeight
{
    double Weight { get; set; }
}
  1. 让所有带重量属性的商品类实现该接口
public class ProductB : Product, IHasWeight
{
    public double Weight { get; set; }
}

// 后续新增带Weight的商品类型,只要实现接口即可,无需修改筛选代码
public class ProductC : Product, IHasWeight
{
    public double Weight { get; set; }
    public string Material { get; set; }
}
  1. 统一筛选逻辑
var filteredProducts = products
    .OfType<IHasWeight>() // 自动过滤所有未实现IHasWeight的类型
    .Where(p => p.Weight > 5)
    .Cast<Product>() // 如需转回Product类型可加这一步
    .ToList();

优势:完全解决新增商品要修改筛选分支的问题,性能无额外损耗,同时支持IEnumerable和IQueryable场景。同理需要按长宽筛选时,可定义IHasDimension接口封装Height、Width属性。


方案3:规格模式(适合复杂多条件筛选场景)

如果筛选规则多、组合逻辑复杂,可将每个筛选规则封装为独立规格类,上层业务只需组合规则即可:

public interface ISpecification<T>
{
    bool IsSatisfiedBy(T entity);
    Expression<Func<T, bool>> ToExpression();
}

public class WeightGreaterThanSpecification : ISpecification<Product>
{
    private readonly double _minWeight;
    public WeightGreaterThanSpecification(double minWeight) => _minWeight = minWeight;

    public bool IsSatisfiedBy(Product entity)
    {
        return entity is IHasWeight hasWeight && hasWeight.Weight > _minWeight;
    }

    public Expression<Func<Product, bool>> ToExpression()
    {
        return p => p is IHasWeight hasWeight && hasWeight.Weight > _minWeight;
    }
}

使用示例:

var spec = new WeightGreaterThanSpecification(5);
var filtered = products.Where(spec.ToExpression()).ToList();

架构备选方案:放弃继承改用属性组合

如果商品属性非常灵活,后续会新增大量不同属性的商品类型,可放弃类继承方案,改为通用Product类+动态属性存储的结构:

public class Product
{
    public string Name { get; set; }
    public double Price { get; set; }
    public ProductType Type { get; set; }
    // 内存场景用字典存扩展属性,数据库场景可对应JSON字段/关联属性表
    public Dictionary<string, object> Attributes { get; set; } = new();
}

筛选时直接从属性集合取值即可,EF Core 7+已原生支持JSON属性查询,可适配数据库端筛选场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 16:24:03