नेविगेशन गुणों से प्राथमिक कुंजी पुनर्प्राप्त करने का सामान्य तरीका

एक इकाई को देखते हुए, मैं संबंधित इकाइयों की प्राथमिक कुंजी को सामान्य तरीके से पुनर्प्राप्त करना चाहता हूं। उदाहरण के लिए: एक ग्राहक के लिए, मैं अपने ऑर्डर के आईडी की एक सूची चाहता हूं।

मेरे प्रयास का वर्तमान हस्ताक्षर:

GetPrimaryKeysOfRelatedEntities(DbContext db, object entity)

मैं एक इकाई के पीके को पुनः प्राप्त करने में सक्षम हूं, और मैं किसी इकाई के नेविगेशन गुणों को पुनर्प्राप्त करने में सक्षम हूं ... लेकिन मुझे किसी इकाई के नेविगेशन गुणों का पीके नहीं मिल सकता है।

मुझे यहाँ एक छोटा लिंक याद आ रहा है!

इकाइयों की कुंजी प्राप्त करने के लिए मेरा कोड यहां दिया गया है, जो नेविगेशन गुणों के लिए काम नहीं करता है

private static IEnumerable GetEntityType(DbContext db, Type entityType)
{
    entityType = ObjectContext.GetObjectType(entityType);

    var metadataWorkspace = ((IObjectContextAdapter)db).ObjectContext.MetadataWorkspace;
    var objectItemCollection = (ObjectItemCollection)metadataWorkspace.GetItemCollection(DataSpace.OSpace);

    ReadOnlyCollection entityTypes = metadataWorkspace.GetItems(DataSpace.OSpace);

    if (entityTypes == null)
    {
        throw new InvalidOperationException();
    }

    var ospaceType = entityTypes.SingleOrDefault(t => objectItemCollection.GetClrType(t) == entityType);

    if (ospaceType == null)
    {
        throw new ArgumentException(
            string.Format("The type '{0}' is not mapped as an entity type.", entityType.Name), "entityType");
    }

    return ospaceType.KeyMembers.Select(k => k.Name);
}

यह कोड EntityType का उपयोग करता है, और मुझे उचित रूप से कुछ और उपयोग करना चाहिए, लेकिन मुझे यकीन नहीं है कि क्या।

0

1 उत्तर

मुझे समस्या नहीं दिखाई दे रही है, आपके पास कोड का एक बड़ा टुकड़ा है जो किसी इकाई की प्राथमिक कुंजी को इसके प्रकार से प्राप्त कर सकता है।

आप अपनी इकाई प्रकार के गुणों की गणना करने के लिए प्रतिबिंब का उपयोग कर सकते हैं और इन गुणों के प्रकार के लिए अपना कोड कॉल कर सकते हैं। इस तरह पूर्व के लिए:

var entityType = entity.GetType();//or another type source
foreach (var prop in type.GetProperties())
{
     if (prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericArguments().Any(x => x.Assembly == type.Assembly))
     {
         var navPropType = prop.PropertyType.GetGenericArguments().First(x => x.Assembly == type.Assembly);
         var keysForThisNavPropType = GetEntityType(db, navPropType);
     }
     else if (prop.PropertyType.Assembly == type.Assembly)
     {
         var keysForThisNavPropType = GetEntityType(db, prop.PropertyType);
     }
}

जैसा कि आप एनवी गुणों को ढूंढने के लिए मानदंड देख सकते हैं, यह है कि इसमें असम्बद्ध रूप से आपके प्राथमिक प्रकार के समान ही है।

संपादित

ठीक है, इसे आजमाएं:

       //we need DbContext vaule
        var db = YOUR_DB_CONTEXT;//assing db context here
       //So we can get ObjectContext instance
        var ctx = ((IObjectContextAdapter) db).ObjectContext;
       //we need some entity to check
        object entity = someYourEntity;//assign your entity here
       //let's get its type
        var type = entity.GetType();

       //helper function to get set name
        Func getEntitySetByObjectType = (t, context) =>
            {
                var container =
                    context.MetadataWorkspace.GetEntityContainer(context.DefaultContainerName, DataSpace.CSpace);

                var entitySet =
                    container.BaseEntitySets.First(item => item.ElementType.Name.Equals(t.Name));

                return container.Name + "." + entitySet.Name;
            };

       //go through the entity's properties
        foreach (var prop in type.GetProperties())
        {
           //nav properties which are collections
            if (prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericArguments().Any(x => x.Assembly == type.Assembly))
            {
                var val = (IEnumerable)prop.GetValue(entity);
                if (val != null)
                {
                   //get value and check if it is not null
                    string setName = null;
                   //go through collection values
                    foreach (var obj in val)
                    {
                        if (setName == null)
                            setName = getEntitySetByObjectType(obj.GetType(), ctx);

                       //get primary key values
                        var entityKey = ctx.CreateEntityKey(setName, obj);
                        Console.WriteLine(entityKey);
                    }
                }
            }
           //nav props which are single objects
            else if (prop.PropertyType.Assembly == type.Assembly)
            {
               //get value and check if it is not null
                var val = prop.GetValue(entity);
                if (val != null)
                {
                   //get primary key values
                    var entityKey = ctx.CreateEntityKey(getEntitySetByObjectType(prop.PropertyType, ctx), val);
                    Console.WriteLine(entityKey);
                }
            }
        }

CreateEntityKey विधि EntityKey क्लास की ऑब्जेक्ट देता है ( http://msdn.microsoft.com/ru-ru/library/system.data.entitykey(v=vs.110).aspx ) जिसमें EntityKeyValues ​​प्रॉपर्टी है जो EntityKeyMember की एक सरणी है। EntityKeyMember में गुण कुंजी और मान हैं जो वास्तव में प्राथमिक कुंजी नाम और मान हैं।

1
जोड़ा
आपके उत्तर के लिए टीएनएक्स। आपके कोड के साथ मैं नेविगेशन प्रॉपर्टी की आईडी का नाम प्राप्त कर सकता हूं, लेकिन इसका मूल्य नहीं। जब मैं Context.Entry (इकाई) का उपयोग कर entityEntry प्राप्त करने का प्रयास करता हूं तो यह विफल हो जाता है। मैं सही प्रकार से गुजरने के साथ संघर्ष कर रहा हूं।
जोड़ा लेखक Jowen, स्रोत
हो सकता है कि यह उतना आसान हो जितना आप सोचते हैं, लेकिन मैं अभी भी इसे काम नहीं कर सकता। NavEntity को भरने का प्रयास करते समय मुझे एक त्रुटि मिलती है। क्या यह पूरी विधि लिखने के लिए बहुत अधिक प्रयास है? मेरे लिए वास्तव में वह सराहनीय होगा!
जोड़ा लेखक Jowen, स्रोत
Thnx टोनी! कोड काम करता है। मुझे केवल prop.GetValue (इकाई, शून्य) में एक अतिरिक्त शून्य पास करना पड़ा .. और CreateEntityKey महत्वपूर्ण है :)
जोड़ा लेखक Jowen, स्रोत
जॉवेन, यदि आपको किसी मूल्य की आवश्यकता है तो आप इसे किसी ऑब्जेक्ट से प्राप्त कर सकते हैं, निम्न कार्य करें: navEntity = prop.GetValue (इकाई, शून्य) और फिर Context.Entry (navEntity)। या मैं कुछ गलत समझता हूँ?
जोड़ा लेखक Tony, स्रोत
कृपया उत्तर में मेरा अपडेट देखें।
जोड़ा लेखक Tony, स्रोत
ओह हाँ, आप सही हो! आपका स्वागत है :)
जोड़ा लेखक Tony, स्रोत