嵌套多映射 Dapper 分页查询中的重复字段名称问题

Posted

技术标签:

【中文标题】嵌套多映射 Dapper 分页查询中的重复字段名称问题【英文标题】:Duplicate field name problem in a nested multi-mapping Dapper pagination query 【发布时间】:2011-09-14 11:26:05 【问题描述】:

我在尝试使用 Dapper 进行多映射以进行分页查询时遇到了问题。

因为我在这个分页场景中使用了嵌套查询,所以嵌套查询中有多个表,我必须加入这些表才能获取我的多映射数据,但其中一些表将共享一些同名字段可以在下面的示例查询中看到(例如iddisplaynameemail):

q = @"select * from (select p.id, p.title, p.etc...,
u1.id, u1.displayname, u1.email,
u2.id, u2.displayname, u2.email,
t.id, t.name,
row_number() over (order by " + sort.ToPostSortSqlClause() + ") as rownum" +
" from posts p" +
" join users u1 on p.owneruserid = u1.id" +
" join users u2 on p.lastediteduserid = u2.id" +
" join topics t on p.topicid = t.id" +
") seq where seq.rownum between @pLower and @pUpper";

在上面的示例中,您可以看到在嵌套查询中,id 字段将出现问题(出现在 posts 表中,users 表连接和 topics 表连接),还有displaynameemail(同时出现在users 表连接中)。

到目前为止,我想到的唯一解决方法是将这些“问题”字段中的每一个都转换为不同的名称,但这涉及在受影响的模型中创建虚拟属性的非常混乱的过程,因此多重映射可以映射到这些,并在我的模型中编辑“真实”属性,如果尚未设置真实值,还可以检查虚拟属性的值。

另外,在上述场景中,我必须创建 x 个虚拟属性,其中 x 是我在查询中的同一个表上可能拥有的连接数(在本例中,同一个用户表上有 2 个连接,因此需要 2 个唯一命名的虚拟属性,仅用于 Dapper 映射目的)。

这显然不理想,而且我肯定会在我创建更多这些多映射分页查询时遇到问题和更多的不整洁。

我希望有一个好的、干净的解决方案来解决这个问题?

【问题讨论】:

我可以想到 2 个选项,1) 在嵌套查询 ) seq join users u1 ... 之外加入您的表... 2) 扩展 SqlBuilder 以支持列别名/取消别名。 (不过它需要元数据)samsaffron.com/archive/2011/09/05/… 谢谢山姆。我已经采纳了你的 2 个建议中的第一个,它们做得很好。如果您发表评论作为答案,我会接受。再次感谢。 【参考方案1】:

我能想到的有两种选择:

选项 1:加入嵌套查询之外的扩展属性:

select s.*, t1.*, t2.* from 
(
select s.*, ROW_NUMBER() OVER (order by somecol) AS RowNumber from Something s
) as X 
left join Table t1 on Id = x.SomeId
left join Table t2 on Id = x.SomeOtherId

选项 2:扩展 SqlBuilder 以处理列别名:

select s.*, /**unalias(Table,t1)**/, /**unalias(Table,t2)**/ from 
        (
        select s.*, /**alias(Table,t1)**/, /**alias(Table,t2)**/ ROW_NUMBER() OVER (order by somecol) AS RowNumber from Something s
        left join Table t1 on Id = x.SomeId
        left join Table t2 on Id = x.SomeOtherId
        ) as X 

然后定义别名宏以使用INFORMATION_SCHEMA.COLUMNS 从数据库中查询和缓存列列表,并为每列添加一个“column as column_t1”字符串。

Unalias 可以很简单地做相反的事情。

【讨论】:

谢谢山姆。在这种情况下,我选择了选项 1,并且效果很好。

以上是关于嵌套多映射 Dapper 分页查询中的重复字段名称问题的主要内容,如果未能解决你的问题,请参考以下文章

.NET CORE:Dapper 映射多对多查询

使用 Dapper 映射 Uri 字段

Dapper入门教程——Dapper Query查询

没有自定义 SQL 的 Dapper 中的多重映射

Dapper 中的多重映射。在 SpiltOn 中接收错误

使用 Dapper 映射嵌套对象列表(3 级嵌套对象)