2010-08-17 17 views
6

यह एक सी # Winforms ऐप है।मैं किसी अन्य ऑब्जेक्ट में ऑब्जेक्ट प्रॉपर्टी के संदर्भ को कैसे संग्रहीत कर सकता हूं?

प्रस्तावना:

मैं एक रूप है कि उपयोगकर्ताओं को मेरी एसक्यूएल सर्वर डेटाबेस में एक मौजूदा MySQL या SQL सर्वर डेटाबेस से डेटा आयात करने की अनुमति देगा बनाने रहा हूँ। यह उपयोगकर्ताओं को नियंत्रण के माध्यम से इसे फिर से दर्ज किए बिना आईपी पते और अन्य डेटा को त्वरित रूप से आयात करने की अनुमति देता है।

उदाहरण:

सरलीकृत, मैं दो वस्तुओं, FieldObject और SensorObject है। FieldObject स्रोत और गंतव्य डेटाबेस फ़ील्ड नाम और प्रकारों को संग्रहीत करने के लिए मौजूद है। SensorObject वह वस्तु है जिसे बाद में मैं डेटाबेस में रिकॉर्ड्स से पॉप्युलेट करता हूं। सादगी के लिए, मैं टाइप हैंडलिंग और अन्य कार्यक्षमता को छोड़ रहा हूं जो प्रश्न के लिए प्रासंगिक नहीं है। (DestinationField के लिए डेटा एक सूची है कि मैं उपयोगकर्ता प्रदान करने के लिए सीमित है, और किसी सरणी या कार्यक्रम के भीतर सूची से आता है।) यहाँ दोनों का एक उदाहरण है:

public class FieldObject 
{ 
    public string DestinationField {get; set;} 
    public string SourceField {get; set;} 
} 

public class SensorObject 
{ 
    public string Name {get; set;} 
    public string IPAddress {get; set;} 
} 

समस्या:

जब उपयोगकर्ता FieldObject के विभिन्न क्षेत्रों को पॉप्युलेट करता है, तो मैं गंतव्य डेटाबेस को पॉप्युलेट करने के लिए जानकारी का उपयोग करता हूं, हालांकि मेरे पास एक बड़ा स्विच स्टेटमेंट है जो गंतव्य फ़ील्ड नाम की जांच करता है यह जानने के लिए कि SensorObject की संपत्ति क्या है।

उदाहरण के लिए:

// Reader is a SqlDataReader with the prerequisite database connection 
FieldObject myField = new FieldObject 
    { 
     DestinationField = "name", 
     SourceField = "proprietary" 
    }; 
SensorObject mySensor = new SensorObject(); 
switch (myField.DestinationField) 
{ 
    case "name": 
     mySensor.Name = Convert.ToString(Reader[myField.DestinationField]); 
     break; 
    case "ip_address": 
     mySensor.IPAddress = Convert.ToString(Reader[myField.DestinationField]); 
     break; 
} 

आप इसे देख वस्तु के लिए और अधिक गुण को संभालने के लिए और अधिक अनावश्यक कोड की आवश्यकता होगी कर सकते हैं।

प्रश्न:

मैं, कि डेटा के अंतर्गत आता है SensorObject की संपत्ति को संग्रहीत करने का कोई रास्ता चाहते हैं ताकि जब किसी सूची में FieldObjects पुनरावृत्ति, मैं प्रभावी रूप से स्विच बयान समाप्त कर सकते हैं।

कुछ की तरह:

foreach(FieldObject f in myFieldList) 
{ 
    mySensor(f.mySensorField) = Convert.ToString(Reader[f.DestinationField]); 
} 

मैं कुछ नहीं कर रहा हूँ सी # में क्या तकनीक ही आवेदन की इस तरह के लिए उधार देता है। मैंने संदर्भ मानों और प्रतिबिंब में देखा है, और न ही उचित लगता है।

मैं इस दृष्टिकोण पर पुनर्विचार करने के लिए किसी अंतर्दृष्टि और सलाह या यहां तक ​​कि तरीकों की सराहना करता हूं।

+0

क्या आप इस समस्या को हल करने के लिए ओआरएम का उपयोग कर सकते हैं ताकि आपको यह अनावश्यक कोड लिखने की आवश्यकता न हो? –

+0

ऑब्जेक्ट रिलेशनल मैपिंग? मुझे संदेह है कि मुझे "ओआरएम" क्या देखना था, मैं इसका उपयोग करने में सक्षम हो सकता था। :) क्षमा करें, अभी भी इनमें से एक नौसिखिया! – JYelton

+0

NHibernate को देखें: http://nhforge.org/wikis/howtonh/your-first-nhibernate-based-application.aspx लंबे समय तक ओआरएम रिलेशनल डेटाबेस के साथ काम करने के अधिकांश दर्द को दूर ले जाता है, हालांकि उन्हें कुछ काम की आवश्यकता होती है आरंभ करना। – Zebi

उत्तर

2

आपको ऐसा करने के लिए प्रतिबिंब का उपयोग करना होगा।

var sensorFields = typeof(SensorObject).GetProperties() 
foreach(var field in fields) 
{ 
    var info = sensorFields.First(sensorField => sensorField.Name == field.Name); 
    var value = Convert.ToString(Reader[field.Destination]); 
    info.SetValue(sensorObj, value, new object[0]); 
} 

GetProperties प्रत्येक प्रॉपर्टी जो मूल्य निर्धारित करने के लिए इस्तेमाल किया जा सकता के लिए एक संपत्ति की जानकारी हो जाता है: की तरह कुछ के रूप में खत्म कर देना चाहिए।

बेशक संपत्ति इंफोस को कैश किया जा सकता है।बस इसे एक बार लिखें और जैसे ही यह चलता है रिफैक्टर। जटिलता से अधिक न करें इसे समयपूर्व अनुकूलन कहा जाता है और सीधे नरक की ओर जाता है;)

+0

यह बहुत उपयोगी लगता है, यह किसी ऐसे व्यक्ति को रखने में मदद करता है जो प्रतिबिंब को समझता है और सही दिशा को इंगित करने के लिए इसका उपयोग करता है! – JYelton

+0

यदि आप लूप सामग्री को 'lookup.Add (field.Name, फ़ील्ड)' के साथ प्रतिस्थापित करते हैं, जहां 'लुकअप' एक 'शब्दकोश <स्ट्रिंग, फ़ील्डइन्फो>' है, तो आपको बाद में इन परिणामों को कैश करने की आवश्यकता है। –

+0

मैं 'रीडर [myField.DestinationField]' पर स्पष्ट नहीं हूं, लेकिन मुझे यकीन नहीं है कि आपको इसे स्ट्रिंग में परिवर्तित करने की आवश्यकता होगी। या, यदि आपने किया, तो मुझे लगता है कि आप 'Convert.ToString (x)' का उपयोग करने के बजाय 'x.ToString()' को कॉल करेंगे। –

1

असल में, प्रतिबिंब एक बुरा विचार नहीं है, खासकर यदि आप प्रत्येक संपत्ति के नाम के लिए PropertyInfo उदाहरणों के साथ एक शब्दकोश को पॉप्युलेट करते हैं।

1

आप इसे प्रतिबिंब के साथ कर सकते हैं। आपको प्रश्न के नाम के साथ प्रॉपर्टी का प्रॉपर्टीइन्फो मिलता है, सेटटर के MethodInfo प्राप्त करें, और उसके बाद इसे आमंत्रित करें।

हालांकि, नाम से संग्रहीत मूल्यों के एक सहयोगी सरणी (शब्दकोश या हेस्टटेबल इत्यादि) को स्टोर करना संभव हो सकता है, जो उचित होने पर निपटने के लिए बहुत आसान होगा।

+1

'PropertyInfo' पर 'GetSetMethod' को कॉल करने का अर्थ हो सकता है, जो सेटर को' MethodInfo 'देता है। –

+0

@ स्टीवन, ठीक है आप हैं। मैं भूल गया था जब ऑब्जेक्ट अपडेट हो रहा था, जिस समय तक मैंने जवाब देना शुरू कर दिया था :) फिक्स्ड, धन्यवाद। –

+1

बस PropertyInfo.SetValue (ऑब्जेक्ट, ऑब्जेक्ट, ऑब्जेक्ट []) – Zebi

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