programing

Dapper Dot Net을 사용하여 데이터베이스 결과에서 사전 개체에 매핑하는 방법은 무엇입니까?

padding 2023. 6. 27. 21:51
반응형

Dapper Dot Net을 사용하여 데이터베이스 결과에서 사전 개체에 매핑하는 방법은 무엇입니까?

다음과 같은 간단한 질문이 있는 경우:

string sql = "SELECT UniqueString, ID  FROM Table";

그리고 다음과 같은 사전 개체에 매핑하고 싶습니다.

Dictionary<string, int> myDictionary = new Dictionary<string, int>();      

대퍼랑 어떻게 해요?

저는 그것이 다음과 같은 것이라고 가정합니다.

myDictionary = conn.Query<string, int>(sql, new {  }).ToDictionary();

하지만 올바른 구문을 찾을 수 없습니다.

이미 다양한 방법이 제시되어 있습니다. 개인적으로 저는 일반적이지 않은 api를 사용할 것입니다.

var dict = conn.Query(sql, args).ToDictionary(
    row => (string)row.UniqueString,
    row => (int)row.Id);
string strSql = "SELECT DISTINCT TableID AS [Key],TableName AS [Value] FROM dbo.TS_TStuctMaster";
Dictionary<string,string> dicts = sqlConnection.Query<KeyValuePair<string,string>>(strSql).ToDictionary(pair => pair.Key, pair => pair.Value);

별칭 및 강력한 유형을 사용할 수 있습니다.

별칭은 KeyValuePair 유형 Key and Value의 특성과 일치하는 키 포인트입니다.

그것은 강력한 타이핑 아래에서 작동하고 잘 작동합니다.

저는 역동적인 타입을 좋아하지 않습니다.그것은 특정한 상황에서 재앙을 가져옵니다.게다가 복싱과 언복싱은 경기력 저하를 가져옵니다.

추가 클래스 없이도 작동합니다.

var myDictionary = conn.Query<string, int, KeyValuePair<string,int>>(sql, (s,i) => new KeyValuePair<string, int>(s,i))
    .ToDictionary(kv => kv.Key, kv => kv.Value);

참고: Dapper.NET 3.5 버전을 사용할 때 첫 번째, 두 번째 및 반환 유형을 사용하는 Query 메서드는 .NET 4.0 및 .NET과 같이 더 많은 매개 변수를 지정해야 합니다.NET 4.5 버전에서는 선택적 인수를 사용합니다.

이 경우 다음 코드가 작동해야 합니다.

string splitOn = "TheNameOfTheValueColumn";
var myDictionary = conn.Query<string, int, KeyValuePair<string,int>>(sql, (s,i) => new KeyValuePair<string, int>(s,i), null, null, false, splitOn, null, null)
        .ToDictionary(kv => kv.Key, kv => kv.Value);

대부분의 인수는 기본값으로 돌아갑니다.splitOn를 입력해야 합니다. 그렇지 않으면 기본값인 'id' 값이 됩니다.

'ID'와 'Description' 두 개의 열을 반환하는 쿼리의 경우,splitOn'Description'으로 설정해야 합니다.

> .net 4.7 또는 net standard2를 사용하는 경우 값 튜플을 사용할 수 있습니다.코드는 멋지고 간결하며 역학을 사용하지 않습니다.

var sql = "SELECT UniqueString, Id  FROM Table";
var dict = conn.Query<(string UniqueString, int Id)>(sql)
           .ToDictionary(t => t.UniqueString,t => t.Id);

Dapper에는 다음에 대한 확장 방법도 있습니다.ExecuteReader따라서 다음과 같은 작업도 수행할 수 있습니다.

var sql = "SELECT UniqueString, ID  FROM Table";
var rows = new List<Dictionary<string, int>>();
using (var reader = cn.ExecuteReader(sql)) {
    while (reader.Read()) {
        var dict = new Dictionary<string, int>();
        for (var i = 0; i < reader.FieldCount; i++) {
            dict[reader.GetName(i)] = reader.GetInt32(i);
        }
        rows.Add(dict);
    }
}

이 방법은 열 이름을 몰라도 작동합니다.또한 데이터 유형을 모르는 경우 변경할 수 있습니다.Dictionary<string,int>로.Dictionary<string,object>그리고.GetInt32(i)로.GetValue(i).

당신이 하려는 일이 가능한지 잘 모르겠습니다.쿼리를 여기에 매핑할 클래스를 정의하면 훨씬 더 사소한 것이 됩니다.

public class MyRow
{
    public int Id { get; set; }
    public string UniqueString { get; set; }
}

그런 다음 다음 작업을 수행합니다.

var sql = "SELECT UniqueString, ID  FROM Table";
var myDictionary = conn.Query<MyRow>(sql).ToDictionary(row => row.UniqueString, row => row.Id);

런타임에 구조를 모르는 테이블의 경우

    using var db = new SqlConnection(_connectionString);
    var sql = $"Select * From {tableName} Order By {primaryKey}";

    var result = await db.QueryAsync(sql); 
    return result
        .Cast<IDictionary<string, object>>()
        .Select(it => it.ToDictionary(it => it.Key, it => it.Value));

저는 개인적으로 다음과 같이 사용하는 것을 선호합니다(라이너 1개).

var dict = dapper.Query<(string, int)>(sql).ToDictionary(x => x.Item1, row => row.Item2);

언급URL : https://stackoverflow.com/questions/14780767/how-to-map-to-a-dictionary-object-from-database-results-using-dapper-dot-net

반응형