不存在从 DbType UInt64 到已知 SqlDbType 的映射。小巧玲珑的 C#

No mapping exists from DbType UInt64 to a known SqlDbType. Dapper C#

我的 SQL Server 2016 数据库中有一个 table 字段(TotalPrice),数据类型为 numeric(20, 3)

我使用 ulong 类型作为我的 C# 属性 类型。

public ulong TotalPrice { get; set; }

当我想在我的 Table 中插入一条记录时,发生了以下异常。

No mapping exists from DbType UInt64 to a known SqlDbType

我的插入记录的C#代码:

const string queryInsertInvoice = @"
INSERT INTO Invoice (CustomerId, Number, TotalPrice, LatestStatusDateTime) 
VALUES (@CustomerId, @Number, @TotalPrice, @LatestStatusDateTime)
SELECT SCOPE_IDENTITY();";

var invoiceId = await dbConnection.QueryFirstOrDefaultAsync<int>(queryInsertInvoice, invoice);

如何使用 Dapper 2.0.53 处理这种情况?

这是故意的。 SQL 服务器没有无符号整数,因此它试图阻止您将数据存储为与您预期不同的东西 - 环绕适用于 equality 操作,但是如果我们允许这样做,不等式运算对于某些值的表现会非常出乎意料。

换句话说:使用long,而不是ulong


编辑:我可以在“Dapper 应该允许前 63 位 ulong - 将其强制为 long - 并抛出异常(OverflowException?)如果MSB 已设置”。只是今天没有实施。

只需将 TotalPrice 类型更改为 decimal。

public decimal TotalPrice { get; set; }

https://docs.microsoft.com/en-us/sql/t-sql/data-types/decimal-and-numeric-transact-sql?view=sql-server-ver15

当我使用 Dapper 时,我所做的是从我的主模型中创建单独的数据 类,以表示 SQL 的结果。使用这些 SqlModel 类,我确保类型与 SQL 中的表示方式完全一致。在我的 C# 业务逻辑中,通常更容易使用 int 或枚举变量,它们可能是 SQL 中的 TINYINT。所以我最终会得到两个 类 这样的:

class UserSqlModel {
  public string Name { get; set; }
  public byte UserTypeId { get; set; }
}

class User {
  public string Name { get; set; }
  public UserType Type { get; set; }
}

然后我会在两个模型之间写一个映射函数。这将您的业务逻辑与 SQL 中数据表示方式的细微差别隔离开来,并允许单独重构您的业务逻辑或 SQL 实现。

在你的例子中,也许你的 SqlModel 会有一个 long 属性 并且你的映射函数会处理 ulonglong 的转换,并且会处理溢出问题。