Dapper 本身不直接支持像 Entity Framework 那样用表达式树动态拼接 WHERE 条件,但可以通过字符串拼接 + 参数化查询的方式安全、灵活地实现动态 WHERE 子句。核心原则是:**条件拼接由代码控制,SQL 参数严格分离,避免 SQL 注入。**
手动拼接 SQL + 动态参数字典
这是最常用、最可控的方式。根据业务逻辑判断哪些条件需要加入 WHERE,逐个追加 SQL 片段,并同步添加对应参数。
用 StringBuilder 或字符串插值(C# 10+)逐步构建 SQL 用 IDictionaryWHERE 1=1开头,后续条件统一用
AND连接,简化逻辑判断
示例:
var sql = new StringBuilder("SELECT * FROM Users WHERE 1=1");
var parameters = new DynamicParameters();
<p>if (!string.IsNullOrWhiteSpace(name))
{
sql.Append(" AND Name LIKE @name");
parameters.Add("@name", $"%{name}%", DbType.String);
}
if (age.HasValue)
{
sql.Append(" AND Age = @age");
parameters.Add("@age", age.Value, DbType.Int32);
}
if (isActive.HasValue)
{
sql.Append(" AND IsActive = @isActive");
parameters.Add("@isActive", isActive.Value, DbType.Boolean);
}</p><p>var users = connection.Query<User>(sql.ToString(), parameters).ToList();
</font></p><H3>使用 Dapper.FastCRUD(第三方扩展)</H3><p>如果你希望更接近 ORM 的写法,<strong>Dapper.FastCRUD</strong> 提供了基于表达式的 Where 构建器,支持链式调用和部分动态条件。</p><ul><li>需安装 NuGet 包:<code>Dapper.FastCRUD</code></li><li>支持 <code>.Where(x => x.Name.Contains(name))</code> 等写法,底层仍转为参数化 SQL</li><li>对简单动态场景友好,但复杂逻辑(如 OR 分组、嵌套括号)仍需手写 SQL</li></ul><p>注意:它不是官方 Dapper 组件,需评估项目长期维护成本。</p><div class="aritcle_card flexRow">
<div class="artcardd flexRow">
<a class="aritcle_card_img" href="/ai/1915" title="Summarizer"><img
src="https://www.herecours.com/d/file/efpub/2026/21-21/20260221140303179509.jpg" alt="Summarizer" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a href="/ai/1915" title="Summarizer">Summarizer</a>
<p>基于 AI 的文本段落摘要生成器</p>
</div>
<a href="/ai/1915" title="Summarizer" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a>
</div>
</div><H3>封装通用动态查询辅助类</H3><p>为避免重复写拼接逻辑,可封装一个轻量工具类,比如 <code>SqlBuilder</code>,负责管理 WHERE 条件和参数。</p><ul><li>内部维护 <code>List<string> _wheres</code> 和 <code>DynamicParameters _params</code></li><li>提供 <code>AddIf(string condition, string paramName, object value)</code> 方法,自动跳过 null/empty 值</li><li>最终调用 <code>BuildSelectSql(string table, string fields = "*")</code> 返回完整 SQL 和参数</li></ul><p>这样业务层只需关注“要不要加这个条件”,不用操心 SQL 拼写和参数命名冲突。</p><H3>慎用字符串格式化或内联变量</H3><p>绝对不要这样写:</p><font color="#888"><pre class="brush:php;toolbar:false;">
// ❌ 危险!SQL 注入漏洞
string sql = $"SELECT * FROM Users WHERE Name = '{name}'";
也不建议用
$"AND Age = {age}" 直接拼数值——即使 int 看似安全,一旦类型变更或传入恶意字符串就失控。Dapper 的安全性完全依赖参数化,绕过它就等于放弃防护底线。
基本上就这些。Dapper 的“动态 WHERE”不是靠魔法,而是靠清晰的条件分支 + 严格的参数隔离。写起来多几行,但稳定、可读、可测试。
