2012-05-24 13 views
11

Ho un problema con MultiMaps in dapper che prova a dividere sulla colonna che contiene NULL. Dapper sembra non istanziare l'oggetto e la mia funzione di mappatura riceve null invece di oggetto.Dapper MultiMap non funziona con splitOn con valore NULL

Ecco il mio nuovo test:

class Product 
    { 
     public int Id { get; set; } 
     public string Name { get; set; } 
     public Category Category { get; set; } 
    } 
    class Category 
    { 
     public int Id { get; set; } 
     public string Name { get; set; } 
     public string Description { get; set; } 
    } 
    public void TestMultiMapWithSplitWithNullValue() 
    { 
     var sql = @"select 1 as id, 'abc' as name, NULL as description, 'def' as name"; 
     var product = connection.Query<Product, Category, Product>(sql, (prod, cat) => 
     { 
      prod.Category = cat; 
      return prod; 
     }, splitOn: "description").First(); 
     // assertions 
     product.Id.IsEqualTo(1); 
     product.Name.IsEqualTo("abc"); 
     product.Category.IsNotNull(); 
     product.Category.Id.IsEqualTo(0); 
     product.Category.Name.IsEqualTo("def"); 
     product.Category.Description.IsNull(); 
    } 

La linea che non riesce è product.Category.IsNotNull(); dovuto al fatto che cat passato alla funzione di mappatura è null.

Ho anche aggiunto di questo metodo per affermare classe:

public static void IsNotNull(this object obj) 
{ 
    if (obj == null) 
    { 
     throw new ApplicationException("Expected not null"); 
    } 
} 
+0

Mi piacerebbe tanto aiutare, ping a Paul su Twitter che scrive github per Windows. So che stanno lavorando duramente per ottenere questa linea che termina il problema trattabile –

+0

@ Samamaffron - grazie per il tuo commento. Se me lo fai sapere una volta risolto, posso spingere le mie modifiche. Potresti copiare il test dal mio post, però - è abbastanza ovvio dove dovrebbero andare le modifiche ;-) PS. Amo Github per Windows. Fammi sapere se potrei essere di qualche aiuto con i test. –

+2

Ho inviato un PR per Dapper che dovrebbe far scomparire questi problemi di fine linea.Fammi sapere se si presentano ancora. Morale della trama: * Copia-incolla [questo file] (https://gist.github.com/2802523#file_the+original+guy+used+autocrlffalse) come '.gitattributes' se il tipo originale ha usato' autocrlf = false '* Copia-Incolla [questo file] (https://gist.github.com/2802523#file_the+original+guy+used+autocrlftrue) come' .gitattributes' se ha usato 'autocrlf = true' –

risposta

14

Questa è "by-design" anche se sarebbe stato ok per rivisitare.

In particolare questo comportamento è lì per aiutare con i join di sinistra. Prendete questo esempio:

cnn.Query<Car,Driver>("select * from Cars c left join Drivers on c.Id = CarId", 
    (c,d) => {c.Driver = d; return c;}) 

Il problema è che se permettiamo di una creazione "coperta" di un oggetto Driver, ogni Car sta per avere un Driver anche quelli in cui il join fallito.

Per risolvere il problema, è possibile scansionare l'intero segmento diviso e verificare che TUTTI i valori siano NULL prima di mappare un oggetto NULL. Questo avrà un impatto perf minimo sul multi-mapper.

Per soluzione alternativa per il vostro caso, si potrebbe inserire una colonna surrogata:

var sql = @"select 1 as id, 'abc' as name, '' as split, 
      NULL as description, 'def' as name"; 
    var product = connection.Query<Product, Category, Product>(sql, (prod, cat) => 
    { 
     prod.Category = cat; 
     return prod; 
    }, splitOn: "split").First(); 
+1

Grazie per la risposta - Vedo il tuo punto. Ho implementato una soluzione simile nel mio progetto usando la chiave primaria della tabella 'Drivers'. La colonna surrogata vuota forza la creazione dell'oggetto per ogni riga, anche quelli che non sono riusciti a far parte dell'unione, quindi per trovare i record mancanti avrei comunque bisogno di controllare tutte le proprietà nella funzione di mappatura. Sarebbe bello se Dapper potesse gestirlo in modo generico invece di controllare più proprietà per 'NULL' in più mappe. Forse qualche bandiera per migliorare il pefr? Un esempio più descrittivo (http://code.google.com/p/dapper-dot-net/) sarebbe ben accetto. –

+1

Mi sono appena imbattuto in questo problema e non ero a conoscenza di questo comportamento prima del tempo. Sarei interessato almeno ad avere un flag 'splitOnNull: true' per evitare questo problema. Dovrà usare le colonne surrogate fino ad allora. –

+0

Non è questo esempio errato, in quanto hai una colonna chiamata "nome" due volte? –

1

Per tutti coloro che vogliono visualizzazione:

divide Dapper per il cognome uguale colonna:

enter image description here

Cambiamo la posizione delle colonne:

problema

enter image description here

nullo:

enter image description here

Scambiato colonna nullo:

enter image description here

Spliton salvato:

enter image description here

Problemi correlati