Closed LeaFrock closed 3 weeks ago
假设SqlServer数据库中有一张表Test,表中有一列字段ActTime。该列采用TimeSpan类型CodeFirst创建——根据FreeSql官方文档,对应的数据库类型为time。
现要将ActTime更新为newActTime(假设是10:00:00):
newActTime
10:00:00
await FreeSql!.Update<Test>() .Where(a => a.Id == id) .Set(a => new Test() { ActTime = newActTime, }) // .Set(a => a.ActTime, newActTime) .ExecuteAffrowsAsync();
出现异常,核心堆栈如下:
System.Exception: 操作数类型冲突: int 与 time 不兼容 ---> Microsoft.Data.SqlClient.SqlException (0x80131904): 操作数类型冲突: int 与 time 不兼容 at Microsoft.Data.SqlClient.SqlCommand.<>c.<ExecuteDbDataReaderAsync>b__188_0(Task`1 result) at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke() at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) --- End of stack trace from previous location --- at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread) --- End of stack trace from previous location --- at FreeSql.Internal.CommonProvider.AdoProvider.ExecuteReaderMultipleAsync(Int32 multipleResult, DbConnection connection, DbTransaction transaction, Func`3 fetchHandler, Action`2 schemaHandler, CommandType cmdType, String cmdText, Int32 cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken) ClientConnectionId:8f782a84-18ac-40b1-bed9-2071877a0c0a Error Number:206,State:2,Class:16 --- End of inner exception stack trace --- at FreeSql.Internal.CommonProvider.AdoProvider.LoggerException(IObjectPool`1 pool, PrepareCommandResult pc, Exception ex, DateTime dt, StringBuilder logtxt, Boolean isThrowException) at FreeSql.Internal.CommonProvider.AdoProvider.ExecuteReaderMultipleAsync(Int32 multipleResult, DbConnection connection, DbTransaction transaction, Func`3 fetchHandler, Action`2 schemaHandler, CommandType cmdType, String cmdText, Int32 cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken) at FreeSql.Internal.CommonProvider.AdoProvider.QueryAsync[T](Type resultType, DbConnection connection, DbTransaction transaction, CommandType cmdType, String cmdText, Int32 cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken) at FreeSql.SqlServer.Curd.SqlServerUpdate`1.<>c__DisplayClass8_0`1.<<RawExecuteUpdatedAsync>b__0>d.MoveNext() --- End of stack trace from previous location --- at FreeSql.Internal.CommonProvider.UpdateProvider`1.ToSqlFetchAsync(Func`2 fetchAsync) at FreeSql.SqlServer.Curd.SqlServerUpdate`1.RawExecuteUpdatedAsync[TReturn](IEnumerable`1 columns, CancellationToken cancellationToken) at FreeSql.Internal.CommonProvider.UpdateProvider`1.<>c__DisplayClass67_0`1.<<SplitExecuteUpdatedAsync>b__0>d.MoveNext() --- End of stack trace from previous location --- at FreeSql.Internal.CommonProvider.UpdateProvider`1.SplitExecuteAsync(Int32 valuesLimit, Int32 parameterLimit, String traceName, Func`1 executeAsync, CancellationToken cancellationToken) at FreeSql.Internal.CommonProvider.UpdateProvider`1.SplitExecuteUpdatedAsync[TReturn](Int32 valuesLimit, Int32 parameterLimit, IEnumerable`1 columns, CancellationToken cancellationToken)
生成错误SQL如下:
UPDATE [Test] SET [ActTime] = 36000
但是,只要换一种Set方式(即换作上方代码注释行),会生成正确的SQL执行成功。
SqlServer 2016
3.2.820
.NET 8
另外是否考虑支持TimeOnly也对应time类型?从语义上来说它比TimeSpan更合适,只是出来得晚了些。
TimeSpan
要考虑前后.net版本问题,暂时还没有兼容。
.Set(a.ActTime, newActTime) 这样解决
原因是前期考虑 TimeSpan 表达式树函数解析,把它转成了毫秒,所以在 lambda 表达式中使用它就解析成 long
问题描述及重现代码:
假设SqlServer数据库中有一张表Test,表中有一列字段ActTime。该列采用TimeSpan类型CodeFirst创建——根据FreeSql官方文档,对应的数据库类型为time。
现要将ActTime更新为
newActTime
(假设是10:00:00
):出现异常,核心堆栈如下:
生成错误SQL如下:
但是,只要换一种Set方式(即换作上方代码注释行),会生成正确的SQL执行成功。
数据库版本
SqlServer 2016
安装的Nuget包
3.2.820
.net framework/. net core? 及具体版本
.NET 8