【问题标题】: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/447stackoverflow.com/questions/5898988/…)。
  • 我不确定您粘贴的链接是否与从 db 查询现有 guid 有关。它看起来像是用于创建指南。我正在尝试从 sql 查询 guid。
  • @ironman UserStuff 类中的属性名为 UId,但 SQL 表中的列名为 u_id。 Dapper 是否会自动进行一些名称匹配以将 u_id 转换为 UId?如果没有,您可以使用别名返回名称为UId 的值吗?
  • @Progman 所以,你是说我的实体中的命名约定必须与表列名完全一致吗?
  • @ironman 看起来有一个东西叫DefaultTypeMap.MatchNamesWithUnderscores。也许这会有所帮助。

标签: c# dapper


【解决方案1】:

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

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

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

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

    using Dapper;
    Dapper.DefaultTypeMap.MatchNamesWithUnderscores = true;
    

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

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

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

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

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

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

【讨论】:

    【解决方案2】:

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

    最简单的方法是调整查询

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

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

    另一个提示: 不要在 SqlServer 中为列名使用下划线。按照 SqlServer 中的约定,我们应该使用大写的列名。

    【讨论】:

      猜你喜欢
      • 2011-12-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-06
      • 2019-11-08
      相关资源
      最近更新 更多