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

如何用DapperExtensions生成带标记枚举的谓词以实现指定SQL WHERE子句

解决DapperExtensions生成位运算WHERE子句的问题

DapperExtensions默认的Operator枚举不包含位运算(&),你之前用Operator.Eq时,会把提前计算的位运算结果作为等值条件传入,这就是生成错误SQL的核心原因。要生成符合预期的位运算WHERE子句,直接使用SqlPredicate构造自定义SQL片段是最直接的方案。

正确实现代码

public string GetPredicateSql(IEnumerable<PlanDetails> planDetails)
{
    var plan = planDetails.FirstOrDefault()?.VIT9010_Plans;
    if (plan == null)
    {
        return string.Empty; // 处理空数据场景
    }

    var predicateGroup = new PredicateGroup
    {
        Predicates = new List<IPredicate>
        {
            // 生成 ([B].[TypeProtectionInfoAdd] & 128 = 0)
            new SqlPredicate($"{nameof(VIT9010_Plans.TypeProtectionInfoAdd)} & 128 = 0"),
            // 生成 ([B].[TypeProtectionId] & 2049 = 2049)
            new SqlPredicate($"{nameof(VIT9010_Plans.TypeProtectionId)} & 2049 = 2049"),
            // 生成 ([B].[TypeProtectionId] & 1024 = 0)
            new SqlPredicate($"{nameof(VIT9010_Plans.TypeProtectionId)} & 1024 = 0")
        },
        Operator = GroupOperator.And
    };

    return GetSqlFromPredicate(predicateGroup);
}

补充说明

  • SqlPredicate支持直接传入自定义SQL条件片段,DapperExtensions会将其原样嵌入WHERE子句,完整保留位运算逻辑。
  • 如果实体类属性和数据库列名存在映射差异(比如用了ColumnAttribute),可以通过类映射器获取真实列名,避免硬编码出错:
// 假设已定义VIT9010_Plans的映射类
var infoAddCol = typeof(VIT9010_Plans).GetMapper().Map(nameof(VIT9010_Plans.TypeProtectionInfoAdd));
new SqlPredicate($"{infoAddCol} & 128 = 0")

可选方案:自定义Operator(复杂度较高)

如果需要复用位运算逻辑,可以扩展Operator枚举并修改SQL生成逻辑,但这种方式需要改动或扩展DapperExtensions源码,一般推荐直接用SqlPredicate快速解决问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 15:38:23