2

I'm new to EF and have hit a roadblock. I'm trying to get a list of navigation properties on entity types that derive from a base type. I was going to use....

ObjectContext objectContext = ((System.Data.Entity.Infrastructure.IObjectContextAdapter)context).ObjectContext;
var entitySetElementType = objectContext.CreateObjectSet<DerivedType>().EntitySet.ElementType;
foreach(var navigationProperty in entitySetElementType.NavigationProperties)
{ //need PropertyInfo here}

This is where I learned I cannot obtain an ObjectSet of a derived type. The exception thrown is

"There are no EntitySets defined for the specified entity type 'SurveyDALv2.Model.Correspondence'. If 'SurveyDALv2.Model.Correspondence' is a derived type, use the base type instead."

I understand I can obtain an ObjectQuery for the derived entities using the

objectContext.CreateObjectSet<BaseType>().OfType<DerivedType>()

But, that doesn't help with obtaining a list of the Navigation Properties (unless I'm missing something). I don't see how to access the EntitySet.NavigationProperties for a derived entity type.

Any help is much appreciated.

Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
Michael
  • 21
  • 2
  • Never tried it with a core Context but can you try this: `CreateObjectSet().OfType()` instead of `CreateObjectSet()` ? – Emmanuel M. May 12 '15 at 14:40
  • Thanks, but I'm looking for a list of the navigation properties defined on a derived-type entity. This (http://stackoverflow.com/questions/17886725/ef5-how-to-get-list-of-navigation-properties-for-a-domain-object works fine for getting a list of navigation properties unless it's a derived-type entity) (the answer from marsman) – Michael May 12 '15 at 15:41

2 Answers2

3
public EntityType ElementType(Type entityType)
{
    var type = ObjectContext.GetObjectType(entityType);
    var objectContext = ((IObjectContextAdapter)this).ObjectContext;
    EntityType elementType;
    if (objectContext.MetadataWorkspace.TryGetItem(type.FullName, DataSpace.OSpace, out elementType))
    {
        return elementType;
    }
    return null;
}
Rick
  • 121
  • 6
0

I managed to make the following code work, i hope it will help you.

    ObjectContext objectContext = ((System.Data.Entity.Infrastructure.IObjectContextAdapter)context).ObjectContext;
    EntityContainer container = objectContext.MetadataWorkspace.GetEntityContainer(objectContext.DefaultContainerName, DataSpace.CSpace);

    //Only works if you keep the default entity associations names pattern
    //ie: ClassName.NavigationProperty
    var t = container.AssociationSets.Where(a => a.Name.Contains(typeof(DerivedType).Name));

    foreach (AssociationSet navigationProperty in t)
    {
        String p = navigationProperty.Name;
        var propInfo = typeof(DerivedType).GetProperty(p.Substring(typeof(DerivedType).Name.Length+1));
    }
Emmanuel M.
  • 441
  • 6
  • 11
  • This does seem to work for most of my entity classes, but I have some entity names that extend other entity names. I have a Correspondence class and CorrespondenceChain class, and CorrespondenceChainItem class. So my class names are preventing the 'Where(a=>a.Name.Contains' from returning only the correct association sets. T – Michael May 14 '15 at 11:37
  • This does help though. I'm really just trying to discover and re-attach an entity's navigation properties to the context prior to adding and saving changes. I've been getting duplicate entities when adding because I'm working with a detached context. I'm just going to write some type-specific stuff to attach the navigation properties I know exist. Thanks – Michael May 14 '15 at 11:47
  • Considering you class names you could have use something like `Where(a => a.Name.Contains(typeof(DerivedType).Name+"."))` note: the `.`may have ben replace by a `_` in the string. Anyway if you got issues duplicating entities maybe you don't retrieve your entity the right way (with include for lazy loading) and i guess you didn't add FK properties to your model allowing you to load your navigation properties according to their known FK. – Emmanuel M. May 15 '15 at 06:46
  • The issue I'm having is summed up here [link](https://msdn.microsoft.com/en-us/magazine/dn166926.aspx), I'm migrating data over from an access db. I'm going to assign the navigation properties using a fk property instead, that should prevent the duplicates. Thanks for the help. – Michael May 15 '15 at 12:51