일반 위키 QueryMultiple 함수

asp.net-mvc c# dapper generics

문제

내 웹 애플 리케이션을위한 asp.net mvc, dapper 및 MySql 저장 프로 시저를 사용하고 있습니다. 지금까지 각 페이지마다 1-3 개의 프로 시저 호출을 저장했습니다. 나는 최근에 나의 호스팅이 단지 10 개의 병렬 연결만을 제공한다는 것을 알았고 그래서 나의 호출을 페이지 당 하나로 결합하고 싶다. 이미 데이터베이스에 필요한 저장 프로 시저를 만들었지 만 문제는 일반적인 방법으로 dapper를 사용하여 프로 시저 결과를 얻는 것입니다.

내가 원한다면 얻을 것이다 일반 함수를 만드는 것입니다 : 1) 저장 프로 시저 이름. 2) 스토어드 프로 시저가 리턴하는 유형 목록. Single / ToList 인 경우 각 유형에 대해 제네릭 함수는 저장 프로 시저의 결과 인 변수 목록을 생성해야합니다.

dapper 페이지의 예제는 비 제네릭 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();
   ...
} 

기본적으로, Customer, Order, Return 타입을 사전에 삽입하여 Single 또는 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

'item'을 (를) 가리키는 위치 : multi.Read ()

내가 도대체 ​​뭘 잘못하고있는 겁니까? dapper의 QueryMultiple을 사용하는 제네릭 함수를 구현하는 더 좋은 방법이 있습니까?

인기 답변

그러나 그것은 다른 사람들에게 도움이 될 수 있다고 생각했습니다. 이 경우 아래 코드를 사용하여 작동하게 할 수 있습니다. 매개 변수로 읽기 함수의 유형을 전달하십시오. 동적으로 되돌릴 수 있습니다. Expando Object를 사용하면 속성을 동적으로 생성 할 수 있습니다.

나는 아래의 객체를 생성하고 함수의 객체 목록을 전달하여 동적 반환 유형을 생성하는 것을 선호합니다.

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

희망이 도움이됩니다.

건배



아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow