为啥 dapper 在进行选择时为 Guid 返回全零但表中的 guid 值设置正确?
Posted
技术标签:
【中文标题】为啥 dapper 在进行选择时为 Guid 返回全零但表中的 guid 值设置正确?【英文标题】:Why is dapper returning all zero's for Guid when doing a select but the guid value in table is set correctly?为什么 dapper 在进行选择时为 Guid 返回全零但表中的 guid 值设置正确? 【发布时间】:2019-05-08 20:23:22 【问题描述】:我正在使用 dapper 从表中查询数据,然后将其转换为对象。当它被转换为对象时,guid 属性设置为全零,但所有其他道具都设置正确。
public class UserStuff
public int Id get; set;
public Guid UId get; set;
public async Task<UserStuff> GetUserStuff(Guid uId)
using(IDbConnection conn = Connection)
string sQuery = "SELECT TOP 100 id, u_id " +
"FROM TestTable WHERE u_id = @u_id ";
conn.Open();
var result = await conn.QueryAsync<UserStuff>(sQuery, new u_id = uId );
return result.FirstOrDefault();
示例 SQL 数据:
标识 | u_id
5 | C9DB345B-D460-4D71-87E0-D9A3B5CE1177
它正在返回: id 为 5,guid 为全零
【问题讨论】:
这似乎是 Dapper 的一个已知问题,请参阅 github.com/StackExchange/Dapper/issues/447 和 ***.com/questions/5898988/…)。 我不确定您粘贴的链接是否与从 db 查询现有 guid 有关。它看起来像是用于创建指南。我正在尝试从 sql 查询 guid。 @ironmanUserStuff
类中的属性名为 UId
,但 SQL 表中的列名为 u_id
。 Dapper 是否会自动进行一些名称匹配以将 u_id
转换为 UId
?如果没有,您可以使用别名返回名称为UId
的值吗?
@Progman 所以,你是说我的实体中的命名约定必须与表列名完全一致吗?
@ironman 看起来有一个东西叫DefaultTypeMap.MatchNamesWithUnderscores
。也许这会有所帮助。
【参考方案1】:
这里的核心问题是你的列名和属性名不同。因此,即使数据库作为 SQL 查询的结果返回值,它也不会映射到您的属性。由于您的属性的数据类型是 GUID
,因此它保留其默认值 - 全为零。
Dapper 映射适用于约定;有点宽泛的话题来讨论。对于您的具体问题,您的列名和属性名应该匹配。如果它们不同,还有其他方法可以使映射正确发生。
我将在这里提出简单的解决方案:
您可以指示 Dapper 在映射时忽略列名中的下划线。
using Dapper;
Dapper.DefaultTypeMap.MatchNamesWithUnderscores = true;
在项目启动时在某处设置此属性。
在 SQL 查询中使用列别名。将您的 SQL 查询更改为如下所示:
SELECT TOP 100 id, u_id as UId....
这样,在不更改列名和属性名的情况下,您将能够正确填写属性,因为现在映射已更正。
要么更改列名称以匹配属性名称,反之亦然。我认为这不切实际。
除了上述之外,dapper 还提供了一个自定义映射。
【讨论】:
【参考方案2】:如果类型和属性相等,Dapper 将列与属性匹配
最简单的方法是调整查询
string sQuery = "SELECT TOP 100 id, u_id as uid " +
"FROM TestTable WHERE u_id = @u_id ";
只是一个提示:
您无需手动打开连接。如果连接状态为closed
,则在查询完成或失败后,Dapper 会为您执行此操作并关闭它。在更复杂的情况下,这可能是必要的,但在您的情况下则不是。
另一个提示: 不要在 SqlServer 中为列名使用下划线。按照 SqlServer 中的约定,我们应该使用大写的列名。
【讨论】:
以上是关于为啥 dapper 在进行选择时为 Guid 返回全零但表中的 guid 值设置正确?的主要内容,如果未能解决你的问题,请参考以下文章
为啥实体框架在直接选择语句中的执行速度比 Dapper 快 [关闭]
为啥我从 Dapper 返回的对象具有 null 和默认属性值?
DB2 - 使用带有字符串数组参数的 Dapper 选择查询将不会返回正确的结果
有时 Dapper 或 System.Data 不会为某些数据库(SQL Server 2012 和 2019)上的简单选择查询返回正确的结果