2012-05-24 60 views
11

我在試圖在包含NULL的列上拆分的Dapper中有MultiMaps問題。 Dapper似乎不會實例化對象,而我的映射函數接收null而不是對象。Dapper MultiMap不能與splitOn一起使用NULL值

這是我的新的測試:

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(); 
    } 

失敗是product.Category.IsNotNull();由於事實cat傳遞給映射功能是null線。

我還添加了這個方法來斷言類:

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

我很樂意幫忙,在Twitter上寫下github for windows。我知道他們正在努力工作,以解決這個問題的結局問題 –

+0

@SamSaffron - 感謝您的評論。如果您在完成整理之後讓我知道,我可以推動我的更改。你可以從我的帖子中複製測試,但是很明顯,這些更改應該放在哪裏;-) PS。我喜歡github的窗戶。讓我知道我是否可以幫助進行測試。 –

+2

我已經發送了適合Dapper的PR,應該讓這些行結束問題消失。讓我知道他們是否仍然出現。故事的道德:*複製粘貼[這個文件](https://gist.github.com/2802523#file_the+original+guy+used+autocrlffalse)作爲'.gitattributes',如果原始人使用'autocrlf = false '*複製粘貼[此文件](https://gist.github.com/2802523#file_the+original+guy+used+autocrlftrue)作爲'.gitattributes',如果他使用'autocrlf = true' –

回答

14

這是「被設計」雖然我將確定重新審視它。

尤其是這種行爲有助於左連接。藉此,例如:

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

麻煩的是,如果我們允許Driver對象的「一刀切」的創作,每Car都將有一個Driver甚至是那些在聯接失敗。

要解決這個問題,我們可以掃描整個被拆分的段,並確保在映射NULL對象之前,所有值都是NULL。這將對多映射器的性能影響很小。

要解決你的情況,你可以插入一個代理列:

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

感謝您的答案- 我明白你的意思。我在使用'Drivers'表的主鍵的項目中實現了類似的解決方法。空白代理列強制每行的對象創建,甚至是失敗的連接,所以爲了找到缺失的記錄,我需要自己檢查映射函數中的所有屬性。如果Dapper能夠以通用的方式處理它,而不是在多個地圖中檢查'NULL'的多個屬性,那就太好了。也許一些標誌來改善pefr?一個更具描述性的例子(http://code.google.com/p/dapper-dot-net/)也會受到歡迎。 –

+1

我剛剛遇到此問題,並未提前知道此行爲。我對至少有一個'splitOnNull:true'標誌感興趣,以避免這個問題。將不得不使用代理列直到那時。 –

+0

是不是這個例子有缺陷,因爲你有一個名爲「名稱」的列兩次? –

1

對於所有誰願意可視化:

小巧玲瓏的分裂由最後等於列名:

enter image description here

讓我們交換列的位置:

enter image description here

空問題:

enter image description here

已換柱空:

enter image description here

Spliton救援:

enter image description here

相關問題