2011-06-29 53 views
6

我在我的工作中使用了LINQ和Dapper的組合。出於性能原因,我正在用Dapper替換我的LINQ代碼。我有很多通過從SQL Server中拖放到Visual Studio數據庫圖表創建的LINQ數據對象。使用LINQ自動生成類型的精簡參數化查詢

在下面的例子中,我已經在內存中有一個LINQ對象,我想將它作爲查詢的參數傳遞給Dapper。例如:

Animal animal = con.Query<Animal>(" select * " + 
     " from animal " + 
     " where animalid = @AnimalId " + 
     " and animaltype = @AnimalType ", 
     cagedAnimal).SingleOrDefault(); 

cagedAnimal包含一個公共屬性AnimalId和AnimalType與getter和setter。

但是在執行此代碼我收到以下錯誤:

The type : SMDApp.Models.Animal is not supported by dapper

下面的代碼不工作:

Animal animal = con.Query<Animal>(" select * " + 
      " from animal " + 
      " where animalid = @AnimalId " + 
      " and animaltype = @AnimalType ", 
      new 
      { 
      AnimalId = cagedAnimal.AnimalId, 
      AnimalType = cagedAnimal.AnimalType 
      } 
      ).SingleOrDefault(); 

它會更方便我特別是在使用現有對象我使用對象的多個屬性作爲查詢的參數。任何人都可以告訴我爲什麼這對匿名對象有效,但不是自動生成的LINQ對象?

編輯迴應本羅賓遜的答覆。

編輯第二次迴應Marc Gravell的答覆。

+1

你是否確定*你正在做'「...」,cagedAnimal)'?你可能在做''...,新的{cagedAnimal})'而不是?基本上 - 這應該已經可以工作了,儘管這會有點浪費,因爲額外的參數可能會被不必要地添加/ –

+1

只是爲了讓您知道我只是推送了一個修復程序,它可以:a忽略查詢中未使用的任何屬性,和b:當它*做鬥爭的時候給出一個更好的錯誤信息。我沒有部署到nuget,但使用新代碼,上面的示例應該可以正常工作 –

+0

期待! –

回答

4

短版本是,應該已經工作;基於錯誤:

The type : SMDApp.Models.CagedAnimal is not supported by dapper

我的結論是無論你實際上傳遞,而不是new {cagedAnimal}cagedAnimal,您CagedAnimal有一個屬性(?Parent,也許),其本身就是一個CagedAnimal,以及短小精悍的可不明白。目前的行爲是,爲所提供的參數對象的每個公共屬性添加一個參數- 並且如果它無法弄清楚如何將任何屬性發送到數據庫,它會抱怨。你應該發現,只有價值成員的簡單POCO可以正常工作。

但是!請注意,它不會嘗試解析您的SQL - 特別是,它不會檢查提供的查詢中的參數。因此,使用POCO方法將意味着您正在爲查詢添加不必要的屬性。

我們短小精悍的廣泛使用,我們只是使用的方法:

new { obj.Foo, obj.Bar, id, key = "something else" } 
+0

謝謝Marc就是這樣。我誤讀了錯誤信息。衛生署!你仍然有一個正確的答案。我已經編輯了現在問題中的錯誤消息。 CagedAnimal類具有Dapper不理解的Animal類型的屬性。 –

+1

@Giles我們計劃改變錯誤信息以包含它正在窒息的屬性名稱(/參數) - 所以你的問題導致了一個積極的變化/結果; p –

+1

@Giles我們也*討論是否或者不根據命令預先過濾我們發送的屬性,即,如果我們在命令文本中可以看到「@ foo」或「:foo」,則只發送'param.foo',這將刪除「不必要的參數」問題 –

3

馬克只是犯了一個變化fix for this issue特別是:

  1. 我們進行一個簡單的驗證發送試圖翻譯之前屬性參數。例如,Dapper不會在這種情況下向服務器發送任何參數:cnn.Query(「select 1」,new {bla = 1})原因「bla」在字符串中不存在。該存儲過程會跳過此驗證。

  2. 這個相當神祕的錯誤現在已經修復並且有了很大的改進。

-

小巧玲瓏用來進行無底層的SQL語句的語法分析,因此,例如:

@"select * 
from animal 
where animalid = @AnimalId" 

包含一個名爲PARAM @AnimalId

它變得複雜的原因,是100%正確,你需要處理邊緣情況下EG:@AnimalId成字符串select '@AnimalId' -- @AnimalId \* @AnimalId *\?正則表達式確實有點棘手,我沒有想過通過每一個邊緣情況。例如:Oracle在其params前加一個:,這使事情更復雜。

由於dapper對字符串中的參數一無所知,因此決定每發送作爲參數。您的一些公共屬性無法映射到DbParameters,因此投訴。