How to make dapper handle SQL Server rowversion as ulong in my POCO?

1

I've seen this other question which is not my problem.

I'm using Dapper multi-mapping for a one to one relationship between two objects. Both of my tables are using rowversion columns (timestamp).

The SQL query, which is a basic SELECT with INNER JOIN, that I'm using is returning a byte array for the rowversion columns. I'd like to mimic the ability of EF Core to specify a field conversion:

// https://github.com/aspnet/EntityFrameworkCore/issues/5936#issuecomment-397987482
 entity.Property(e => e.RowVersion)
     .HasConversion(new NumberToBytesConverter<ulong>())
     .IsRowVersion();

The dapper mapping is failing with the following error:

System.Data.DataException
  HResult=0x80131501
  Message=Error parsing column 17 (RowVersion=System.Byte[] - Object)
  Source=Dapper.StrongName
  StackTrace:
   at Dapper.SqlMapper.ThrowDataException(Exception ex, Int32 index, IDataReader reader, Object value) in C:\projects\dapper\Dapper\SqlMapper.cs:line 3609
   at Dapper.SqlMapper.<>c__DisplayClass156_0`8.<GenerateMapper>b__0(IDataReader r) in C:\projects\dapper\Dapper\SqlMapper.cs:line 1542
   at Dapper.SqlMapper.<MultiMapImpl>d__153`8.MoveNext() in C:\projects\dapper\Dapper\SqlMapper.cs:line 1444
   at System.Collections.Generic.List`1.AddEnumerable(IEnumerable`1 enumerable)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Dapper.SqlMapper.<MultiMapAsync>d__52`8.MoveNext() in C:\projects\dapper\Dapper\SqlMapper.Async.cs:line 949
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at TestDapper.Program.<RunSQLCommand>d__17`3.MoveNext() in C:\Users\olivier.matrot\dapper\Program.cs:line 544
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at TestDapper.Program.<RunSQLCommand>d__17`3.MoveNext() in C:\Users\olivier.matrot\dapper\Program.cs:line 561
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at TestDapper.Program.<Main>d__8.MoveNext() in C:\Users\olivier.matrot\dapper\Program.cs:line 374
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at TestDapper.Program.<Main>(String[] args)

Inner Exception 1:
InvalidCastException: Object must implement IConvertible.

I'm pretty sure that the Inner Exception message is not the way to go. Any help appreciated.

EDIT:


Solved it by using a TypeHandler:

public class ULongTypeHandler : SqlMapper.TypeHandler<ulong>
{
    public override ulong Parse(object value)
    {
        return (ulong)new NumberToBytesConverter<ulong>().ConvertFromProvider(value);
    }

    public override void SetValue(IDbDataParameter parameter, ulong value)
    {
        throw new NotImplementedException();
    }
}

But this would apply for all ulong properties on the POCOs.

c#
dapper
asked on Stack Overflow May 24, 2019 by Olivier MATROT • edited May 24, 2019 by Olivier MATROT

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0