Dapper无法从SELECT CASE查询中找到POCO映射

时间:2018-11-20 16:04:28

标签: c# sql-server dapper

我正在使用Dapper从SQL Server数据库中提取信息。有关信息的POCO如下。

public class Client
    {
        public string ShortName { get; set; }
        public string ContactDetail { get; set; }
        public string Street { get; set; }
        public string District { get; set; }
        public string Town { get; set; }
        public string County { get; set; }
        public string Postcode { get; set; }
    }

当我使用查询为以下对象提取上述对象的信息时,除下一行max(case when cd.Type = 1 OR cd.Type = 2 then cd.Detail end) as 'ContactDetail'之外,所有信息均已正确映射,我相信这可能是因为我不是简单地从表列中提取数据我事先使用CASE子句进行了一些处理,因此Dapper无法找到将信息映射到的正确位置。

我认为包括AS子句将帮助Dapper找到正确的映射,但这实际上不起作用。

如何更改查询,以便Dapper可以正确映射ContactDetail数据?

select 
tp.ShortName as 'ShortName', 
max(case when cd.Type = 1 OR cd.Type = 2 then cd.Detail end) as 'ContactDetail',
tp.Street, 
tp.District, 
tp.Town, 
tp.County, 
tp.PostCode
... (rest of query snipped as unneeded)

我知道查询可以正常工作,因为我可以在SSMS中运行它并返回正确的信息。

2 个答案:

答案 0 :(得分:1)

Dapper对查询中的内容没有任何兴趣或了解,它仅关心结果的形状。因此:无论发生什么-这都是查询的一部分。

我的预感是:

  • 数据确实丢失和/或null
  • null处理和null合并有关,也许与max使事情复杂化

请注意,您不能只是与SSMS输出进行比较,因为SSMS和ADO.NET(SqlClient)可能具有不同的SET选项默认值,这可能会导致某些查询之间仍然存在细微差别。

正确进行调查,我真的需要一个可重现的示例(大概带有假数据);没有这个,我们有点猜测。

但是要重申:

我强烈怀疑,如果您通过ExecuteReader或类似的查询执行相同的查询,则会发现返回该位置的值确实为null(或DBNull)。

答案 1 :(得分:0)

我非常确定问题在于,如果您在Dapper中使用对象映射器(即<>中的Client),那么它将仅在匹配表中查找那些列。 “ ContactDetail”不存在(它是派生的),因此找不到它。

根据您的数据和用例,这里有两个选择。

  • 从Dapper获取原始数据,然后使用Linq(或类似方法)通过程序中的逻辑派生ContactDetail。

  • 根据您的查询编写存储过程,并使用Dapper运行它

  • 使用Dapper的Query命令运行您的SQL语句,而不是尝试直接映射对象。

让我知道您是否对此感到困惑,或者需要进一步的解释。