使用带有 Dapper 的 TableValuedParameter 将字符串转换为 smalldatetime 失败
Using TableValuedParameter with Dapper Conversion Fails for string to smalldatetime
使用 dapper 将数据表转换为 TableValuedParameter 时出现此错误。我在转换为数据表时是否遗漏了某些内容,DBNull.Value 是否适用于可为空的日期时间?是否存在我在我的代码中没有看到的错误映射 属性?
System.Private.CoreLib: Exception while executing function: MyProject. Core .Net SqlClient Data Provider: Conversion failed when converting character string to smalldatetime data type.
我创建数据列表到数据表
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)
用户定义 Table 是
CREATE TYPE [dbo].[PersonData] AS TABLE(
PersonId int NOT NULL
,SomeString varchar(50) null
,StartDate smalldatetime null
,EndDate smalldatetime null
,CurrentDate smalldatetime null)
问题是因为对象的序列化使列的顺序不同于用户定义的顺序Table,所以他们试图将日期保存到字符串列中。我将对象更改为此并且错误已解决,请注意属性的顺序已更改:
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; }
}
使用 dapper 将数据表转换为 TableValuedParameter 时出现此错误。我在转换为数据表时是否遗漏了某些内容,DBNull.Value 是否适用于可为空的日期时间?是否存在我在我的代码中没有看到的错误映射 属性?
System.Private.CoreLib: Exception while executing function: MyProject. Core .Net SqlClient Data Provider: Conversion failed when converting character string to smalldatetime data type.
我创建数据列表到数据表
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)
用户定义 Table 是
CREATE TYPE [dbo].[PersonData] AS TABLE(
PersonId int NOT NULL
,SomeString varchar(50) null
,StartDate smalldatetime null
,EndDate smalldatetime null
,CurrentDate smalldatetime null)
问题是因为对象的序列化使列的顺序不同于用户定义的顺序Table,所以他们试图将日期保存到字符串列中。我将对象更改为此并且错误已解决,请注意属性的顺序已更改:
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; }
}