使用LINQ自動生成類型的Dapper參數化查詢

c# dapper linq

我在工作中使用了LINQ和Dapper的組合。出於性能原因,我正在用Dapper替換我的LINQ代碼。我通過從SQL Server拖放到Visual Studio數據庫圖表中創建了很多LINQ數據對象。

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

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

cagedAnimal包含帶有getter和setter的公共屬性AnimalId和AnimalType。

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

類型:dapper不支持SMDApp.Models.Animal

以下代碼確實有效:

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的回复。

一般承認的答案

短版本應該已經有效了 ;根據錯誤:

類型:dapper不支持SMDApp.Models.CagedAnimal

我得出結論,要么你實際上傳遞new {cagedAnimal}而不是cagedAnimal或者你的CagedAnimal有一個屬性( Parent ,也許?),它本身就是一個CagedAnimal ,而且這個dapper無法理解。當前的行為是為所提供的參數對象的每個公共屬性添加一個參數 - 如果它無法弄清楚如何將任何屬性發送到數據庫,它會抱怨。您應該會發現只有值成員的簡單POCO可以正常工作。

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

我們廣泛使用短小精悍,我們只使用這種方法:

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

熱門答案

Marc特別緻力於修改這個問題

  1. 在發送嘗試將屬性轉換為params之前,我們執行了一個簡單的驗證。例如,在這種情況下,Dapper不會向服務器發送任何參數:cnn.Query(“select 1”,new {bla = 1})因為字符串中不存在“bla”。對於存儲過程,將跳過此驗證。

  2. 這個相當神秘的錯誤現在已得到修復並得到了很大改善。

-

Dapper過去不執行底層SQL語句的解析,例如:

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

包含一個名為@AnimalId參數。

它變得複雜,要100%正確你需要處理邊緣情況EG: @AnimalId到字符串中select '@AnimalId' -- @AnimalId \* @AnimalId *\ ?正則表達式確實有點棘手,我沒有想過每個邊緣情況。例如:Oracle為其參數添加了一個前綴:這使事情複雜化。

由於dapper對字符串中的params一無所知,因此決定將每個公共財產作為參數發送。您的某些公共屬性無法映射到DbParameters因此它抱怨。



許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因