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

时间:2019-05-08 20:23:23

标签: 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();
  }
}

示例SQL数据:

id | u_id

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

正在返回: ID为5,GUID为全零

2 个答案:

答案 0 :(得分:3)

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

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

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

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

    using Dapper;
    Dapper.DefaultTypeMap.MatchNamesWithUnderscores = true;
    

    在项目启动时的某个地方设置此属性。

  2. 在SQL查询中使用列别名。将您的SQL查询更改为以下内容:

    SELECT TOP 100 id, u_id as UId....
    

    这样,无需更改列名和属性名,就可以正确填充属性,因为现在已纠正了映射。

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

除上述内容外,dapper还提供了一个自定义映射。

答案 1 :(得分:0)

如果类型和属性相等,则Dapper将列与属性匹配

最简单的方法是调整查询

    string sQuery = "SELECT TOP 100 id, u_id as uid " +
                    "FROM TestTable WHERE u_id = @u_id ";

只是一个提示: 您无需手动打开连接。如果连接状态为closed,则查询完成或失败后,Dapper会为您执行此操作并关闭它。在更复杂的情况下,这可能是必需的,但在您的情况下则没有必要。

另一个提示: 请勿在SQLServer中对列名使用下划线。按照SqlServer中的约定,我们应该使用大写字母列名称。