2014-07-14 7 views
7

La versione breve

SqlMapper.Query<T> sembra ignorare la mia registrati TypeHandler<T>TypeHandler <T> non sembra di essere chiamato

La versione lunga

Ecco una semplice query:

SELECT 'Foo' AS CategoryName, 200 AS CategoryRating 

. ..e qui ci sono due POCO:

public class RatingValue 
{ 
    public Int32 Value { get; set; } 
    // ... some other properties etc ... 
} 

public class MyResult 
{ 
    public String CategoryName { get; set; } 
    public RatingValue CategoryRating { get; set; } 
} 

Ho creato un nuovo TypeHandler di attuazione che dovrebbe trasformare quel CategoryRating Int32 in un oggetto RatingValue:

public class RatingValueHandler: SqlMapper.TypeHandler<RatingValue> 
{ 
    public override RatingValue Parse(object value) 
    { 
     if (value is Int32) 
      return new RatingValue() { Value = (Int32)value }; 

     throw new FormatException("Invalid conversion to RatingValue"); 
    } 

    public override void SetValue(System.Data.IDbDataParameter parameter, RatingValue value) 
    { 
     // ... null, range checks etc ... 
     parameter.DbType = System.Data.DbType.Int32; 
     parameter.Value = Int32.Parse(value.Value); 
    } 
} 

Ora, prima di eseguire la mia domanda Sto aggiungendo il mio nuovo gestore in questo modo:

SqlMapper.AddTypeHandler<RatingValue>(new RatingValueHandler()); 

Tuttavia, quando ho eseguito questo:

c.Query<MyResult>("SELECT 'Foo' AS CategoryName, 200 AS CategoryRating"); 

Ricevo un'eccezione da Dapper: non è stato possibile analizzare i risultati nella colonna 1. I previsto Dapper per attivare il gestore di tipo personalizzato!

Penso che mi manchi qualcosa di molto, molto ovvio. Per favore dimmi quanto sono sciocco!

risposta

5

Non sei sciocco; sono io; quanto segue ora passa localmente (spinto a github); sarà distribuire a NuGet prestonow available on NuGet in v1.27 e sopra:

public void SO24740733_TestCustomValueHandler() 
{ 
    Dapper.SqlMapper.AddTypeHandler(RatingValueHandler.Default); 
    var foo = connection.Query<MyResult>(
     "SELECT 'Foo' AS CategoryName, 200 AS CategoryRating").Single(); 

    foo.CategoryName.IsEqualTo("Foo"); 
    foo.CategoryRating.Value.IsEqualTo(200); 
} 

public void SO24740733_TestCustomValueSingleColumn() 
{ 
    Dapper.SqlMapper.AddTypeHandler(RatingValueHandler.Default); 
    var foo = connection.Query<RatingValue>(
     "SELECT 200 AS CategoryRating").Single(); 

    foo.Value.IsEqualTo(200); 
} 
+0

Perché ringraziamento - una punta di cappello a voi, signore :) – Dan

+0

Che dire SqlMapper.AddTypeHandler (nuova StringDictionaryValueHandler()); public class StringDictionaryValueHandler: SqlMapper.TypeHandler > {...} –