2011-11-15 8 views
9

जिज्ञासा से बाहर मैं चाहते हैं पता है कि कैसे सबसे अच्छा एक वर्ग है कि CA1006 चेतावनी से बचने के लिएCA1006 से बचने के लिए जेनेरिक आईनेमेरेबल या IDictionary को कैसे कार्यान्वित करें?

CA1006 इस्तेमाल किया जा सकता लागू करने के लिए: Microsoft.Design: एक डिजाइन पर विचार करें जहां 'IReader.Query (स्ट्रिंग, स्ट्रिंग) 'जेनेरिक प्रकार घोंसला नहीं है' IList (IDictionary (स्ट्रिंग, ऑब्जेक्ट का)) '।

इस विधि है कि जेनेरिक प्रकार

public virtual IList<IDictionary<string, object>> Query(
    string fullFileName, 
    string sheetName) 
{ 
    using (var connection = new OdbcConnection(
     this.GetOdbcConnectionString(fullFileName))) 
    { 
     connection.Open(); 
     return connection 
      .Query(string.Format(
       CultureInfo.InvariantCulture, 
       SystemResources.ExcelReader_Query_select_top_128___from__0_, 
       sheetName)) 
      .Cast<IDictionary<string, object>>() 
      .ToList(); 
    } 
} 

कुछ

तरह
SourceData<T, U> Query(string fullFileName, string sheetName) 
SourceData Query(string fullFileName, string sheetName) 

संपादित रिटर्न है:

मार्क के सुझावों के बाद मैं इस वर्ग में नेस्टेड जेनेरिक समझाया

public class QueryRow : List<KeyValuePair<string, object>> 
{ 
    protected internal QueryRow(IEnumerable<KeyValuePair<string, object>> dictionary) 
    { 
     this.AddRange(dictionary.Select(kvp => kvp)); 
    } 
} 
+0

शब्दकोशों की सूची का उद्देश्य क्या है? क्या वह पंक्तियां हैं, जो कि महत्वपूर्ण मूल्यों के साथ हैं (यानी कॉलम-नाम से एक्सेस की गई कोशिकाओं)? –

+0

प्रत्येक शब्दकोश एक पंक्ति है जहां प्रत्येक कुंजी स्तंभ शीर्षलेख है और मान सेल मान – mrt181

+0

'Cast' के स्थान पर आप '.ToDictionary' का उपयोग नहीं कर सकते हैं? – IAbstract

उत्तर

12

सबसे पहले, ध्यान दें कि यह एक डिजाइन दिशानिर्देश है, संकलक त्रुटि नहीं। यहां एक वैध दृष्टिकोण होगा: इसे अनदेखा करें।

कोई अन्य हो सकता है - इसे समेकित करें; यानी के बाद से इस व्यवसायिक द्वारा ही पहुंचा जा रही है वापसी एक List<QueryRow>, जहां QueryRow एक इंडेक्सर के साथ एक IDictionary<string,object> पर एक उथले आवरण है, यानी

public class QueryRow { 
    private readonly IDictionary<string,object> values; 
    internal QueryRow(IDictionary<string,object> values) { 
     this.values = values; 
    } 
    public object this[string key] { 
     get { return values[key]; } 
     set { values[key] = value; } 
    } 
} 

तो, भरने के माध्यम से:

var data = connection.Query(....) 
     .Select(x => new QueryRow((IDictionary<string,object>)x).ToList() 

एक अन्य विकल्प (जो मैं बेहद शौकीन नहीं हूं), हो सकता है: DataTable लौटाएं।

DataTable टाइप करने के बाद अपने हाथ धोने के लिए चला गया ... gah! दो बार अब

+0

जब मैं वापसी डेटाटेबल पढ़ता हूं तो लगभग लगभग पक्की होती है;) – mrt181

+0

ठीक है, मैंने इसे इस तरह से आजमाया। काम नहीं करता। मैं यह संदेश प्राप्त 'System.ArgumentNullException: Parametername: चोर बी System.Reflection.Emit.DynamicILGenerator.Emit (opcode opcode, ConstructorInfo चोर) बी Dapper.SqlMapper.GetClassDeserializer (IDataReader पाठक, Int32 startBound, Int32 लंबाई, Boolean returnNullIfFirstMissing) SqlMapper.cs में: लाइन 1227.' जब मैं पैरामीटर रहित कन्स्ट्रक्टर जोड़ता हूं, क्वेरी एक आईनेमरेबल देता है लेकिन मान संपत्ति शून्य है। – mrt181

+0

@ एमआरटी वाह, पूरी तरह से ध्यान नहीं दिया कि यह "डैपर" था। मूल प्रश्न में कुछ भी मुझे "डैपर" का सुझाव नहीं दिया! लेकिन: इस मामले में, आप गैर-जेनेरिक क्वेरी() विधि का उपयोग करने में सक्षम होना चाहिए, फिर बारी में प्रत्येक को कास्ट करें, यानी 'connection.Query (....)। चुनें (x => new QueryRow ((IDictionary ) x)। टॉलिस्ट() '- कोई उपयोग? –

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