使用 Dapper 扩展自定义 SQL

Posted

技术标签:

【中文标题】使用 Dapper 扩展自定义 SQL【英文标题】:Customizing SQL with Dapper Extensions 【发布时间】:2012-10-17 08:56:14 【问题描述】:

我正在为我的一些类型使用 Dapper Extensions,它对大多数用例都非常有效。我遇到了一个多对多关系的案例,我想做这样的事情:-

SELECT id,a,b,c FROM Foo WHERE Foo.id in (SELECT foo_id FROM foo-bar WHERE bar-id=@bar_id)

显然,Dapper Extensions 可以处理“SELECT id,a,b,c FROM Foo”,但不能处理后半部分。我可以进行选择以获取我想要的 Foo id 列表,然后将其传递给 Dapper Extensions,但效率较低。

我不能用普通的 Dapper 做的部分是自动获取 SELECT 列列表,所以我真正想要的是一种方法:-

从 Dapper Extension 的内部机制中获取 SELECT 列列表 从 Dapper Extension 的内部机制中获取基本的“SELECT id,a,b,c FROM Foo” Hook Dapper Extensions 获取代码,以便我可以添加自定义 WHERE 子句

我查看了代码,但不知道如何做这些事情。任何人都可以帮忙吗?目前我已经通过使用普通的 Dapper 和“SELECT * ...”来解决问题,但我确信有更好的方法。

【问题讨论】:

【参考方案1】:

这是另一种选择:

你可以创建一个视图:

select * from Foo 
join FooBar b
on a.foo_id = b.foo_id

然后使用谓词选择任何where子句:

using (SqlConnection cn = new SqlConnection(_connectionString))

    cn.Open();
    var predicate = Predicates.Field<Foo>(f => f.foo_id, Operator.Eq, 1);
    IEnumerable<Foo> list = cn.GetList<Foo>(predicate);
    cn.Close();

生成的 SQL 应该类似于:

SELECT 
   [Foo].[foo_id]
 , [Foo].[...]
 , [Foo].[...]
 , [Foo].[...]
 , [Foo].[...] 
FROM [ViewName] 
WHERE ([ViewName].[foo_id] = @foo_id_0)

【讨论】:

【参考方案2】:

我不知道这在 2012 年是不支持的。所以两年内大约有 1.7K 的观看次数,曝光率并不高。但是,如果 Dapper 的新手来到这里并想知道它是否有效,答案是,它有效。在撰写本文时,使用最新版本的Dapper v1.42 from nuget:

var sql = "SELECT id,a,b,c FROM Foo WHERE Foo.id in (
    SELECT foo_id FROM foo-bar WHERE bar-id=@bar_id)"
using (var cn = new SqlConnection(the_connection_string)) 
  cn.Open();
  var returnedObject = cn.Query<dynamic>(sql, new  bar_id = some_value );

【讨论】:

以上是关于使用 Dapper 扩展自定义 SQL的主要内容,如果未能解决你的问题,请参考以下文章

Dapper扩展SQL跟踪及全局缓存通知

Dapper - 如何将记录作为自定义对象类型返回?

未调用 Dapper 自定义 SqlMapper.TypeHandler Parse 方法

.NETCore Sqlserver下对Dapper的扩展支持

基于Dapper的开源Lambda超轻量扩展,Dapper.Common

如何使用自定义属性扩展 IdentityUser