从DbType UInt64到已知SqlDbType的映射不存在精巧的C#

问题描述

我在sql Server 2016数据库中有一个表字段(TotalPrice),数据类型为numeric(20,3)

我将ulong类型用作C#属性类型。

public ulong TotalPrice { get; set; }

当我想在表中插入记录时,发生以下异常。

从DbType UInt64到已知的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 Server没有无符号整数,因此它试图防止您将数据存储为与期望的值不同的内容-对于 equality 操作来说,环绕法是可以的,但是对于等式操作,不等式操作的行为会非常意外如果我们允许的话,一些值。

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


编辑:我可以在“ Dapper应该允许ulong的前63位中强制出售-将其强制为long-并在MSB抛出并抛出异常(OverflowException?)的情况下出售”设置”。只是今天还没有实现。

,

只需将TotalPrice类型更改为十进制即可。

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的转换并处理溢出问题。 / p>