2014-09-19 50 views
1

我爲我的web應用程序使用asp.net mvc,dapper和MySql存儲過程。 到目前爲止,每個頁面都有1-3個存儲過程調用。 我最近發現我的主機只提供10個並行連接,所以我想將每個頁面的呼叫合併爲一個。 我已經在數據庫中做了必要的存儲過程,但我的問題是以通用方式使用dapper來獲取過程結果。通用短小精悍QueryMultiple函數

我想要的是使一個通用函數,將得到: 1)存儲過程的名稱。 2)存儲過程返回的類型列表。並且對於每個類型(如果它是Single/ToList)。 通用函數應該產生一個變量列表,這是存儲過程的結果。

在短小精悍的頁面的例子顯示瞭如何使非通用QueryMultiple電話:

var sql = 
@" 
select * from Customers where CustomerId = @id 
select * from Orders where CustomerId = @id 
select * from Returns where CustomerId = @id"; 

using (var multi = connection.QueryMultiple(sql, new {id=selectedId})) 
{ 
    var customer = multi.Read<Customer>().Single(); 
    var orders = multi.Read<Order>().ToList(); 
    var returns = multi.Read<Return>().ToList(); 
    ... 
} 

基本上,我要的是插入的客戶,訂單,返回類型爲一個字典,註明每他們是單身或ToList,然後像做:

var result = new List<dynamic>(); 
var sql = 
@" 
select * from Customers where CustomerId = @id 
select * from Orders where CustomerId = @id 
select * from Returns where CustomerId = @id"; 

using (var multi = connection.QueryMultiple(sql, new {id=selectedId})) 
{ 
    foreach(var item in dictionary) 
    { 
     if (item.Value.equals("Single")) 
      result.Add(multi.Read<item.Key>().Single()); 
     else if (item.Value.equals("ToList")) 
      result.Add(multi.Read<item.Key>().ToList()); 
    } 
} 
return result; 

我的問題是,Visual Studio中說:

The type or namespace name 'item' could not be found 

指向'項目':multi.Read()

我在做什麼錯了? 有沒有更好的方法來實現一個使用Dapper的QueryMultiple的泛型函數?

+0

字典從不設置? – user3036342 2014-09-19 12:25:42

+0

我不關注,你是什麼意思字典從來沒有設置? 錯誤是在調試期間而不是運行時。您的代碼爲: – shahaf 2014-09-19 12:27:41

+0

:foreach項目在字典中。沒有數據被加載到字典中,所以項目不會被聲明,這意味着它不能被發現 – user3036342 2014-09-19 12:28:34

回答

1

雖然這是一個老話題,但認爲它可能會幫助其他人。在這種情況下,你可以使用下面的代碼來使它工作。在Read函數中輸入參數。你可以返回動態。使用Expando對象可以動態地生成屬性。

我寧願創建類似下面的對象,並將對象的傳遞列表傳遞給將爲您生成動態返回類型的函數。

public class MapItem 
{ 
    public Type Type { get; private set; } 
    public DataRetriveTypeEnum DataRetriveType { get; private set; } 
    public string PropertyName { get; private set; } 

    public MapItem(Type type, DataRetriveTypeEnum dataRetriveType, string propertyName) 
    { 
     Type = type; 
     DataRetriveType = dataRetriveType; 
     PropertyName = propertyName; 
    } 
} 

//And then make a reusable function like below 

public async Task<dynamic> ExecuteQueryMultipleAsync(IDbConnection con, string spName, object param = null,IEnumerable<MapItem> mapItems = null) 
    { 
     var data = new ExpandoObject(); 

     using (var multi = await con.QueryMultipleAsync(spName,param, commandType:CommandType.StoredProcedure)) 
     { 
      if (mapItems == null) return data; 

      foreach (var item in mapItems) 
      { 
       if (item.DataRetriveType == DataRetriveTypeEnum.FirstOrDefault) 
       { 
        var singleItem = multi.Read(item.Type).FirstOrDefault(); 
        ((IDictionary<string, object>) data).Add(item.PropertyName, singleItem); 
       } 

       if (item.DataRetriveType == DataRetriveTypeEnum.List) 
       { 
        var listItem = multi.Read(item.Type).ToList(); 
        ((IDictionary<string, object>)data).Add(item.PropertyName, listItem); 
       } 
      } 

      return data; 
     } 
    } 

下面你如何調用上面的方法:

var mapItems = new List<MapItem>() 
     { 
      new MapItem(typeof(YourObject1), DataRetriveTypeEnum.FirstOrDefault, "Object1"), 
      new MapItem(typeof(YourObject2), DataRetriveTypeEnum.List, "Object2") 
     }; 

     var response = await ExecuteQueryMultipleAsync(name, request, mapItems); 

     var object1 = response.Result.Object1; 
     var listOfObject2 = ((List<dynamic>)response.Result.Object2).Cast<YourObject2>(); 

希望這有助於。

乾杯

+0

不錯的做法,我喜歡這樣做。很高興看到dapper的stackoverflow /創建者團隊會使用類似的方法說出什麼。 – 2017-01-14 18:06:49

相關問題