1

I have the following piece of code (example simplified a bit):

public class Entity
{
    public int Id { get; set; }
    public TimeSpan Duration { get; set; }
    ...
}

...

public void Save(Entity e)
{
    if (e.Id == 0)
        _connection.Insert(e);
    else
        _connection.Update(); 
}

The database is an Sql Server 2008R2, and Duration field is of the Time sql datatype.

When I call Save on a new entity, i.e. Id is 0, then the insert statement succeeds fine. When calling Save on an existing entity, I get the exception:

System.InvalidCastException occurred
  HResult=-2147467262
  Message=Failed to convert parameter value from a TimeSpan to a DateTime.
  Source=TechTalk.SpecFlow
  StackTrace:
       at System.Data.SqlClient.SqlParameter.CoerceValue(Object value, MetaType destinationType, Boolean& coercedToDataFeed, Boolean& typeChanged, Boolean allowStreaming)
       at System.Data.SqlClient.SqlParameter.GetCoercedValue()
       at System.Data.SqlClient.SqlParameter.Validate(Int32 index, Boolean isCommandProc)
       at System.Data.SqlClient.SqlCommand.BuildParamList(TdsParser parser, SqlParameterCollection parameters)
       at System.Data.SqlClient.SqlCommand.BuildExecuteSql(CommandBehavior behavior, String commandText, SqlParameterCollection parameters, _SqlRPC& rpc)
       at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite)
       at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite)
       at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean asyncWrite)
       at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
       at Dapper.SqlMapper.ExecuteCommand(IDbConnection cnn, IDbTransaction transaction, String sql, Action`2 paramReader, Object obj, Nullable`1 commandTimeout, Nullable`1 commandType) in c:\Dev\Dapper\Dapper NET40\SqlMapper.cs:line 2034
       at Dapper.SqlMapper.Execute(IDbConnection cnn, String sql, Object param, IDbTransaction transaction, Nullable`1 commandTimeout, Nullable`1 commandType) in c:\Dev\Dapper\Dapper NET40\SqlMapper.cs:line 730
       at DapperExtensions.DapperImplementor.Update[T](IDbConnection connection, T entity, IDbTransaction transaction, Nullable`1 commandTimeout) in c:\Data\Projects\Nuget Projects\DapperExtensions\DapperExtensions\DapperImplementor.cs:line 140

I have the latest NuGet versions of Dapper and DapperExtensions installed.

Why does the Insert succeed, and the Update does not? Is there a workaround I can use?

So far, I have manually created the update sql to be called, but this is far from ideal. This simple example works:

_connection.Execute("update Entity set Duration=@Duration, ... where Id=@Id",
    new {
        e.Id,
        e.Duration,
        ...
    });
Pete
  • 12,206
  • 8
  • 54
  • 70

0 Answers0