为什么在执行选择时 dapper 为 Guid 返回全零,但表中的 guid 值设置正确?

iro*_*man 4 c# dapper

我正在使用 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();
  }
}
Run Code Online (Sandbox Code Playgroud)

示例 SQL 数据:

身份证 | u_id

5 | C9DB345B-D460-4D71-87E0-D9A3B5CE1177

它返回:id 为 5,guid 全为零

Ami*_*shi 5

这里的核心问题是您的列名和属性名不同。因此,即使该值作为 SQL 查询的结果由数据库返回,它也不会映射到您的属性。由于您的属性的数据类型是GUID,它保留其默认值 - 全为零。

Dapper 映射适用于约定;讨论的话题有点广泛。对于您的特定问题,您的列名和属性名应该匹配。如果这些不同,还有其他方法可以使映射正确发生。

我将在这里提出简单的解决方案:

  1. 您可以指示 Dapper 在映射时忽略列名中的下划线。

    using Dapper;
    Dapper.DefaultTypeMap.MatchNamesWithUnderscores = true;
    
    Run Code Online (Sandbox Code Playgroud)

    在项目启动时在某处设置此属性。

  2. 在 SQL 查询中使用列别名。将您的 SQL 查询更改为如下所示:

    SELECT TOP 100 id, u_id as UId....
    
    Run Code Online (Sandbox Code Playgroud)

    这样,在不更改列名和属性名的情况下,您将能够正确填写属性,因为现在更正了映射。

  3. 更改列名称以与属性名称匹配,反之亦然。我不认为这是实用的。

除了上述之外,还有一个可用于 dapper 的自定义映射。