2013-02-08 16 views
39

अगर मैं इस तरह के रूप में एक सरल प्रश्न हैं:डैपर डॉट नेट का उपयोग कर डेटाबेस परिणामों से किसी शब्दकोश ऑब्जेक्ट को कैसे मैप करें?

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

और मैं इस तरह के रूप में एक शब्दकोश वस्तु को यह मैप करना चाहते हैं:

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

मैं इस डैप्पर के साथ क्या होगा?

मुझे लगता है यह कुछ इस तरह है:

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

लेकिन उचित सिंटैक्स को समझ नहीं सकता।

उत्तर

67

पहले से दिखाए गए विभिन्न तरीके हैं; व्यक्तिगत रूप से मैं सिर्फ गैर सामान्य एपीआई का उपयोग करेंगे:

var dict = conn.Query(sql, args).ToDictionary(
    row => (string)row.UniqueString, 
    row => (int)row.Id); 
+0

को स्पष्टीकरण के लिए धन्यवाद मुझे यह भी एहसास नहीं हुआ कि आप क्वेरी विधि में रिटर्न प्रकार छोड़ सकते हैं। – jpshook

+2

एफवाईआई।लौटने वाले क्षेत्रों के लिए उन संपत्ति नाम केस संवेदनशील हैं। ओरेकल में खेतों को मेरे पास लौटाया जा रहा था, इसलिए सभी पूंजी अक्षरों में उदाहरण के लिए पंक्ति थी। यूनिकस्ट्रिंग ओरेकल से पंक्ति के रूप में वापस आ रही थी। अनियंत्रण। –

+1

@ अन्य आरडीबीएमएस के बाद से कॉलिन केस संवेदनशील नामों के लिए अनुमति देता है (इसलिए .foo, .FOO और .Foo सभी अलग हैं) मुझे यकीन नहीं है कि मैं इसके बारे में बहुत कुछ कर सकता हूं, कहने के अलावा "जो भी आपकी आरडीबीएमएस लौटाता है" –

5

मुझे यकीन नहीं है कि आप जो करने की कोशिश कर रहे हैं वह संभव है। आप क्वेरी मैप करने के लिए एक वर्ग को परिभाषित यदि यह कहीं अधिक तुच्छ हो जाता है: एक अतिरिक्त वर्ग के बिना

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

वर्क्स भी:

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

उसके बाद, आप सिर्फ इस करना होगा

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 संस्करण का उपयोग करते समय, क्वेरी विधि जो पहले, दूसरे और वापसी प्रकारों को लेती है, आपको अधिक पैरामीटर निर्दिष्ट करने की आवश्यकता होती है, .NET 4.0 और .NET 4.5 संस्करण optional arguments का लाभ उठाते हैं।

इस मामले में, निम्नलिखित कोड काम करना चाहिए:

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 की आवश्यकता है, के रूप में यह अन्यथा 'आईडी' के एक मूल्य लागू हो जाएगी।

एक प्रश्न है कि दो कॉलम देता है, 'आईडी' और 'विवरण' के लिए, splitOn करने के लिए 'विवरण' स्थापित किया जाना चाहिए।

+1

टिम - आपका समाधान पूरी तरह से मान्य है, लेकिन मैं सादगी के लिए मार्क को पसंद करता हूं। – jpshook

+0

क्या आप समझा सकते हैं * अतिरिक्त कक्षा के बिना भी काम करता है * क्या आप इसका मतलब है कि मुझे [मार्क्स समाधान] (http://stackoverflow.com/a/14786328/542251) के लिए कक्षा की आवश्यकता है? न तो वास्तव में यह – Liam

+1

@Liam बताता है: मुझे लगता है कि मैं [w.brian's] (http://stackoverflow.com/a/14781485/284240) दृष्टिकोण का जिक्र कर रहा था। –

4

डैप्पर भी 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) बदल सकते हैं।

संबंधित मुद्दे