在C# .NET6 API项目中,Dapper不支持TimeOnly数据类型。

6

我正在使用Dapper在一个ASP.NET Core 6 Web API项目中,后端数据库是SQL Server 2016。Dapper的ExecuteScalar方法返回了一个错误。

类型为System.TimeOnly的成员DepartureTime不能用作参数值

有什么解决办法吗?

public virtual int Create(TModel entity)
{
    int result = -1;
    var insertQuery = QueryGenerator.GenerateInsertQuery(typeof(TModel));
    var factory = new SqlServerDbConnectionFactory(connectionString);
    var profiler = CustomDbProfiler.Current;

    using (var connection = ProfiledDbConnectionFactory.New(factory, profiler))
    {
        try
        {
            if (connection.State == ConnectionState.Closed)
            {
                connection.ConnectionString = connectionString;
                connection.Open();
            }

            result =  connection.ExecuteScalar<int>(insertQuery, entity, transaction: null); // Throwing error
        }
        catch (Exception e)
        {
            var sql = profiler.GetCommands();
            throw;
        }
    }

    return result;
}

insertQuery 包含以下查询:

INSERT INTO [Flight] ([FlightNumber], [SourceCode], [DestinCode],[DepartureTime], [EffectDate], [Stops], [TravelMinutes]) 
VALUES (@FlightNumber, @SourceCode, @DestinCode, @DepartureTime, @EffectDate, @Stops, @TravelMinutes);
SELECT SCOPE_IDENTITY()

entity 是类型为 FlightModel 的实体:

public class FlightModel
{
    public int Id { get; set; }
    public string FlightNumber{ get; set; }
    public string SourceCode{ get; set; }
    public string DestinCode { get; set; }
    public TimeOnly DepartureTime{ get; set; }
    public DateOnly EffectDate { get; set; }
    public int Stops{ get; set; }
    public int TravelMinutes { get; set; }
}
2个回答

7

这里开始,自定义您自己的类型处理程序:

将以下内容添加到您的配置中:

SqlMapper.AddTypeHandler(new SqlTimeOnlyTypeHandler());
public class SqlTimeOnlyTypeHandler : SqlMapper.TypeHandler<TimeOnly>
{
    public override void SetValue(IDbDataParameter parameter, TimeOnly time)
    {
        parameter.Value = time.ToString();
    }

    public override TimeOnly Parse(object value)
    {
        return TimeOnly.FromTimeSpan((TimeSpan)value);
    }
}

SetValue 应该使用 time.ToTimeSpan() 而不是 time.ToString(),对吗? - Dan Guzman
@DanGuzman:你为什么这么说?记住 - 这个处理程序只关心将“TimeOnly”值通过数据访问层传递到数据库中。 - Jim G.
1
由于SQL Server时间数据类型映射到.NET TimeSpan,因此我认为参数值应该是TimeSpan类型。但是,关于dapper类型处理程序,我不知道的很多,所以我会听从您的专业意见。 - Dan Guzman
1
类似的方法也可以用于“DateOnly”类型。 - Scuzzlebutt

-2

您可以使用 TimeSpan

public class FlightModel
{
    ...
    public TimeSpan DepartureTime{ get; set; }
    public DateTime EffectDate { get; set; }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接