使用 TableValuedParameter 和 Dapper 将字符串转换为 smalldatetime 失败
Posted
技术标签:
【中文标题】使用 TableValuedParameter 和 Dapper 将字符串转换为 smalldatetime 失败【英文标题】:Using TableValuedParameter with Dapper Conversion Fails for string to smalldatetime 【发布时间】:2020-04-21 07:43:21 【问题描述】:使用 dapper 将数据表转换为 TableValuedParameter 时出现此错误。我在转换为数据表时遗漏了什么,DBNull.Value 是否适用于可为空的日期时间?是否存在我在代码中没有看到的映射错误的属性?
System.Private.CoreLib:执行函数时出现异常:MyProject。 Core .Net SqlClient 数据提供程序:将字符串转换为 smalldatetime 数据类型时转换失败。
我在数据表中创建数据列表
List<PersonData> personDatas = maps.Select( mappedData =>
new PersonData
PersonId = mappedData.PersonId,
StartDate = mappedData.StartDate,
EndDate = mappedData.EndDate,
CurrentDate = DateTime.Now,
SomeString = mapped.SomeStringData
)
.ToList()
.ToDataTable();
Method for ToDataTable can be found here
PersonData 定义为
public class PersonData
public int PersonId get; set;
public DateTime? StartDate get; set;
public DateTime? EndDate get; set;
public string SomeString get; set;
public DateTime? CurrentDate get; set;
然后我像这样用 Dapper 执行查询
using (var cn = new SqlConnection(connectionString))
cn.Open();
//This is where the exception happens
cn.Execute(RepositorySql.MergeSql(), new
UserDefinedTable = dataTable.AsTableValuedParameter("[dbo].[PersonData]")
);
cn.Close();
Sql 是
MERGE dbo.tblPersonData AS target
USING @UserDefinedTable AS source
ON target.PersonID = source.PersonID
WHEN MATCHED
THEN UPDATE SET
StartDate = source.StartDate,
EndDate = source.EndDate,
--UpdatedDate instead of InsertedDate
UpdatedDate = source.CurrentDate,
SomeString = source.SomeString
WHEN NOT MATCHED BY TARGET
THEN
--Inserted date instead of UpdatedDate
INSERT(PersonID, StartDate, EndDate, InsertedDate, SomeString)
VALUES
(source.PersonId, source.StartDate, source.EndDate, source.CurrentDate, source.SomeString)
用户定义表是
CREATE TYPE [dbo].[PersonData] AS TABLE(
PersonId int NOT NULL
,SomeString varchar(50) null
,StartDate smalldatetime null
,EndDate smalldatetime null
,CurrentDate smalldatetime null)
【问题讨论】:
【参考方案1】:问题是因为对象的序列化将列的顺序与用户定义表的顺序不同,因此他们试图将日期保存到字符串列中。我将对象更改为 this 并解决了错误,请注意属性的顺序已更改:
public class PersonData
public int PersonId get; set;
public string SomeString get; set;
public DateTime? StartDate get; set;
public DateTime? EndDate get; set;
public DateTime? CurrentDate get; set;
【讨论】:
以上是关于使用 TableValuedParameter 和 Dapper 将字符串转换为 smalldatetime 失败的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 php 和 mysql 使用纬度和经度进行几何搜索
Cocoa - 为啥使用 NSInteger 和 CGFloat 而不是使用 int 和 float,或者总是使用 NSNumber?