2011-08-31 13 views
28

मुझे कैसे पता चलेगा कि कक्षा की कौन सी संपत्ति इकाई फ्रेमवर्क कोड प्रथम इकाई पीओसीओ की प्राथमिक कुंजी है?इकाई फ्रेमवर्क कोड पहले। प्राथमिक कुंजी

कृपया ध्यान दें कि आईडी/कक्षा नाम + "आईडी" के लिए स्ट्रिंग मिलान एक खराब विकल्प है। एंटिटी फ्रेमवर्क द्वारा उपयोग किए जाने वाले सम्मेलन को खोदने और विश्वसनीय रूप से प्रमुख संपत्ति प्राप्त करने का कोई तरीका होना चाहिए।

अग्रिम धन्यवाद।

उत्तर

50

आप प्राप्त करने के लिए कुंजी गुण के नाम (वहाँ अधिक एक तो हो सकता है) मानचित्रण मेटाडाटा पूछ सकते हैं:

ObjectContext objectContext = ((IObjectContextAdapter)dbContext).ObjectContext; 
ObjectSet<YourEntity> set = objectContext.CreateObjectSet<YourEntity>(); 
IEnumerable<string> keyNames = set.EntitySet.ElementType 
              .KeyMembers 
              .Select(k => k.Name); 

एक बार जब आप कुंजी नाम आप उनके मूल्यों तक पहुँचने के लिए प्रतिबिंब का उपयोग कर सकते है।

जैसा कि आप देख सकते हैं कि दृष्टिकोण ऑब्जेक्ट कॉन्टेक्स्ट एपीआई पर वापस आ जाता है क्योंकि डीबीकॉन्टेक्स्ट एपीआई केवल साधारण परिदृश्यों के लिए है जहां आप मेटाडेटा मैपिंग जैसे विवरणों से परेशान नहीं हैं।

+1

Thx। उत्तर के रूप में चिह्नित किया गया। मुझे टिप्पणी करना है कि आपके संदर्भ वर्ग (उदाहरण के लिए, IYourDataContext) में एक इंटरफ़ेस जोड़ने और IObjectContextAdapter को IYourDataContext में प्राप्त करना बेहतर विचार है। इस तरह आपको इसे कास्ट करने की ज़रूरत नहीं है। –

+0

यह देखते हुए कि यह अब 5 पुराना है, क्या भारी प्रतिबिंब के बिना ऐसा करने का कोई तरीका है? मेरे प्रश्न का संदर्भ ट्रैकिंग के बिना एक खोज विधि को कार्यान्वित करने का प्रयास है, जैसे सिंगलऑर्डफॉल्ट() लेकिन बेस क्लास में जो इकाई के मुख्य नाम को नहीं जान सकता है। धन्यवाद दोस्तों। –

+0

बहुत बहुत धन्यवाद, एक आकर्षण की तरह काम –

22

यदि यह किसी की मदद करता है, तो मुझे इसे पहले से जानने के बिना ऐसा करने में सक्षम होना चाहिए (इसलिए मैं आसानी से CreateObjectSet<YourEntity>() नहीं कर सका क्योंकि मुझे YourEntity नहीं पता था), इसलिए मैं @ लाडस्लाव को अनुकूलित करने में सक्षम था निम्नलिखित में के समाधान:

// variable "type" is a System.Type passed in as a method parameter 
ObjectContext objectContext = ((IObjectContextAdapter)this.context).ObjectContext; 
IEnumerable<string> retval = (IEnumerable<string>)objectContext.MetadataWorkspace 
    .GetType(type.Name, type.Namespace, System.Data.Entity.Core.Metadata.Edm.DataSpace.CSpace) 
    .MetadataProperties 
    .Where(mp => mp.Name == "KeyMembers") 
    .First() 
    .Value; 

तरह का अजीब लगता है कि MetadataWorkspace.GetType एक System.Type के बजाय, प्रकार नाम और नाम स्थान के तार की आवश्यकता है, लेकिन यह है कि सबसे अच्छा मैं मिल सकता है।

+0

Thanx, तुमने मेरा जीवन बचाया! –

7

तालिका प्रति प्रकार विरासत के कारण मुझे उपर्युक्त दृष्टिकोण दोनों में समस्या थी। मेरे काम कर संस्करण (@ S'pht'Kr के समाधान लेकिन DataSpace.OSpace इस कारण के लिए नहीं DataSpace.CSpace का उपयोग कर के आधार पर) नीचे है:

 protected IEnumerable<string> GetKeyPropertyNames() 
     { 
      var objectContext = ((System.Data.Entity.Infrastructure.IObjectContextAdapter) this.Context).ObjectContext; 

      return GetKeyPropertyNames(typeof (TEntity), objectContext.MetadataWorkspace); 
     } 

     private static IEnumerable<string> GetKeyPropertyNames(Type type, MetadataWorkspace workspace) 
     { 
      EdmType edmType; 

      if (workspace.TryGetType(type.Name, type.Namespace, DataSpace.OSpace, out edmType)) 
      { 
       return edmType.MetadataProperties.Where(mp => mp.Name == "KeyMembers") 
        .SelectMany(mp => mp.Value as ReadOnlyMetadataCollection<EdmMember>) 
        .OfType<EdmProperty>().Select(edmProperty => edmProperty.Name); 
      } 

      return null; 
     } 
+0

बहुत बढ़िया।जिसने मुझे –

9

एफई 6.1 में वहाँ है एक Db() विस्तार विधि इस आसान बना देता है कि।

उदाहरण:

public static IEnumerable<string> GetPrimaryKeyPropertyNames(DbContext db, Type entityType) 
{ 
    return db.Db(entityType).Pks.Select(x => x.PropertyName); 
} 
+0

की मदद की हालांकि इसका प्रदर्शन कैसा रहा? अंतर्निहित प्रतिबिंब के साथ भारी? –

+0

मुझे नहीं पता, EntityFramework मेरे ज्ञान के साथ शुरू करने के लिए बहुत से प्रतिबिंब के आधार पर है। – angularsen

+0

अंजद: अच्छा बिंदु। –

2

उपयोगकर्ता rashleighp तरह, मैं भी का एक संस्करण चाहता था उपयोगकर्ता Ladislav Mrnka के जवाब दें कि संकलन समय पर प्रकार को जानने की आवश्यकता के बजाय केवल रनटाइम पर प्रकार को जानना आवश्यक है। उपयोगकर्ता rashleighp की तरह, उपयोगकर्ता S'pht'kr का समाधान मेरे लिए काम नहीं किया, लेकिन उसके समाधान काम किया। नीचे, मैं अपने वार्तालाप का एक सरल संस्करण प्रदान करके इस बातचीत में योगदान देता हूं जो मेरे लिए काम करता है। हालांकि, मैंने अभी उपयोगकर्ता एजेड्रिया द्वारा समाधान के बारे में सीखा है और यही वह है जिसका मैं उपयोग करूँगा।

// variable "type" is a System.Type passed in as a method parameter 
((IObjectContextAdapter)context) 
    .ObjectContext 
    .MetadataWorkspace 
    .GetItem<EntityType>(type.FullName, DataSpace.OSpace) 
    .KeyProperties 
    .Select(p => p.Name); 
संबंधित मुद्दे