2014-09-19 5 views
1

Я использую asp.net mvc, dapper и MySql хранимые процедуры для своего веб-приложения. До сих пор для каждой страницы у меня было 1-3 вызова хранимых процедур. Недавно я узнал, что мой хостинг предоставляет только 10 параллельных подключений, поэтому я хочу совместить свои звонки на одну страницу. Я уже сделал необходимые хранимые процедуры в базе данных, но моя проблема заключается в использовании dapper в общем виде для получения результатов процедур.Generic dapper QueryMultiple function

Я хочу создать общую функцию, которая получит: 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; 

Моя проблема, визуальная студия говорит:

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

Указание на «товар» в: multi.Read()

Что я делаю неправильно? Есть ли лучший способ реализовать универсальную функцию, использующую QueryMultiple dapper?

+0

словарь не установлен? – user3036342

+0

i dont follow, что вы подразумеваете, словарь никогда не устанавливается? ошибка во время отладки не выполняется. – shahaf

+0

Ваш код читает: foreach item в словаре. Никакие данные никогда не загружаются в словарь, поэтому элемент никогда не будет объявлен, что означает, что его невозможно найти – user3036342

ответ

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

Надеется, что это помогает.

Cheers

+0

Хороший подход, мне это нравится. Было бы неплохо увидеть, что команда в stackoverflow/создатели dapper скажут об использовании подобного подхода. –

Смежные вопросы