2011-05-01 18 views
9


जो मैं करने की कोशिश कर रहा हूं वह एक इकाई ऑब्जेक्ट को विधि में पास करना और इसमें गुणों के सभी नाम वापस करना है।
मैं सभी रंगमंच की सामग्री के नाम प्राप्त करने के लिए इस कोड का उपयोग कर रहा हूँ:किसी संस्था में गुणों के सभी नाम कैसे प्राप्त करें?

return classObject.GetType().GetProperties(); 

समस्या यह है कि इस कोड को वापसी "EntityKey" और "EntityState" गुण के रूप में whe मैं इसे इकाई वस्तु के साथ उपयोग करें।
क्या ऐसा करने का कोई तरीका है?

अग्रिम में Thanx

+1

तो, क्या आपको अपनी सारी चीज़ें "EntityKey" और "EntityState" मिल रही हैं या क्या वे दो ही हैं जिन्हें आप वापस प्राप्त कर रहे हैं? –

+0

@ बाला आर: मुझे हर चीज मिलती है जो मैंने – Dabbas

उत्तर

22

आप सभी प्रत्यक्ष गुण नहीं, बल्कि आधार प्रकार है, जो अपने मामले में EntityObject है के गुणों हैं:

var type = classObject.GetType(); 
//alternatively call out directly: typeof(EntityObject).GetProperties()... 
var basePropertyNames = type.BaseType.GetProperties().Select(x => x.Name); 
var props = type.GetProperties().Where(p => !basePropertyNames.Contains(p.Name)); 

यह नमूना मान लिया गया है वहाँ एक आधार प्रकार है (जो पहले डीबी के लिए मामला है), जब इसकी गारंटी नहीं है तो रिफैक्टर।

@ मैट की टिप्पणी से संपादित: उपरोक्त सभी अनावश्यक है, इस के बारे में सोच नहीं करने के लिए मेरे सिर पर तमाचा सकता है - सिर्फ सही बाध्यकारी झंडे का उपयोग करें: BrokenGlass द्वारा कहा गया है

return classObject.GetType().GetProperties(BindingFlags.DeclaredOnly | 
              BindingFlags.Public | 
              BindingFlags.Instance); 
+5

का उल्लेख किया है 'classObject.GetType() का उपयोग क्यों नहीं करें। GetProperties (बाइंडिंगफ्लैग्स। केवल घोषित) '? –

+4

@ मैट: क्योंकि मैं एक आईडी * ओटी-मेरा जवाब बदल रहा हूं – BrokenGlass

+2

और @ मैट: उत्तर के लिए धन्यवाद। @ ब्रोकनग्लस: जब मैंने @ मारर्स के संशोधित कोड का उपयोग किया, तो मुझे गुण मिलते हैं लेकिन मुझे कुछ गुण भी मिलते हैं जो मुझे नहीं चाहिए कि नेविगेशन गुण कौन सा है, इसलिए मैंने कोड को थोड़ा सा संशोधित किया और अब यह काम किया: 'var basePropertyNames = classObject .GetType()। बेस टाइप। गेटप्रॉपर्टीज()। चुनें (x => x.Name); रिटर्न क्लासऑब्जेक्ट.गेट टाइप()। GetProperties()। जहां (पी =>! बेसप्रॉपर्टी नाम। कंटेनर (पी .नाम) &&! पी। प्रॉपर्टी टाइप टाइप। आईसी क्लास)। चुनें (x => x.Name); ' मुझे नहीं पता कि यह सभी संस्थाओं के लिए काम करेगा या नहीं .. – Dabbas

1

लेकिन सावधान रहना अगर आपको प्रदर्शन की ज़रूरत है और आप इसे लूप में करना चाहते हैं। प्रतिबिंब एक तेज़ चीज नहीं है।

यदि आपको प्रदर्शन की आवश्यकता है तो आप स्ट्रिंग्स या किसी भी चीज के रूप में गुणों को पुनर्प्राप्त करने के लिए अपनी बेस क्लास में वर्चुअल विधि डालना चाहेंगे, और सभी व्युत्पन्न कक्षाओं में इसे ओवरराइड कर सकते हैं। यह उपवास दृष्टिकोण होगा लेकिन अधिक कोडिंग के साथ।

2

मुझे एक ही समस्या थी। मुझे मिला समाधान मैं गुणों के नाम के साथ एक सरणी बनाने के लिए था (मुझे olnly कुछ की जरूरत है)। आपके मामले में, चूंकि यह सभी गुणों का ट्रैक रखने के लिए श्रमिक हो सकता है, इसलिए मैं गुण EntityKey और EntityState फ़िल्टर कर दूंगा और अन्य सभी को वापस कर दूंगा। कोड कुछ इस तरह होगा: अगर वहाँ एक बेहतर समाधान है

public IEnumerable<PropertyInfo> GetProperties() 
{ 
    Type t = this.GetType(); 

    return t.GetProperties() 
     .Where(p => (p.Name != "EntityKey" && p.Name != "EntityState")) 
     .Select(p => p).ToList(); 
} 

पता नहीं है, लेकिन यह अच्छा होगा;) आशा है कि यह मदद करता है!

7

यह भी प्रतिबिंब के बिना संभव है:

using (var context = new ModelContainer()) 
{ 
    // Access CSDL 
    var container = context.MetadataWorkspace 
          .GetEntityContainer(context.DefaultContainerName, DataSpace.CSpace); 
    // Access name of related set exposed on your context 
    var set = container.BaseEntitySets[context.YourEntitySet.EntitySet.Name]; 
    // Access all properties 
    var properties = set.ElementType.Members.Select(m => m.Name).ToList(); 
    // Access only keys 
    var keys = set.ElementType.KeyMembers.Select(m => m.Name).ToList(); 
} 

आप देख सकते हैं आप और अधिक तो नाम की पहुंच है। उदाहरण दिखाता है कि अब आप कौन सी संपत्ति कुंजी का हिस्सा हो सकते हैं। यदि आप सीधे Members तक पहुंचते हैं तो आप जान सकते हैं कि कौन सी संपत्ति स्केलर, जटिल प्रकार या नेविगेशन प्रॉपर्टी है।

सभी जानकारी पहले ही लोड हो चुकी है इसलिए प्रतिबिंब की कोई आवश्यकता नहीं है। यदि आप प्रतिबिंब का उपयोग करना चाहते हैं तो इसे केवल एक बार उपयोग करना न भूलें (पहली बार आपको इसकी आवश्यकता हो) और फिर प्राप्त संपत्ति नामों को संग्रहीत और पुन: उपयोग करें। प्रतिबिंब धीमा है इसलिए जब भी आपको नामों की आवश्यकता होती है तो इसका उपयोग करना एक बुरा अभ्यास है।

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