5

Is there any way to see if property of an entity is navigation property, from its metadata?

I can determine if property is entity collection by inspecting if it implements ICollection and from there i can conclude if it is navigation property.

But what about if property is not entity collection but only reference to another entity?

Milos Mijatovic
  • 955
  • 1
  • 17
  • 34
  • 1
    Make each entity implement an AbstractEntity and do an (entity is AbstractEntity) check ? – Dante Apr 20 '12 at 19:57

3 Answers3

6

You can get the O-Space EDM entity type from MetdataWorkspace and it has NavigationProperties property. Here is an example:

var workspace = ((IObjectContextAdapter) ctx).ObjectContext.MetadataWorkspace;
var itemCollection = (ObjectItemCollection)(workspace.GetItemCollection(DataSpace.OSpace));
var entityType = itemCollection.OfType<EntityType>().Single(e => itemCollection.GetClrType(e) == typeof(MyEntity));
foreach(var navigationProperty in entityType.NavigationProperties)
{
    Console.WriteLine(navigationProperty.Name);
}
Stevenfowler16
  • 880
  • 1
  • 7
  • 22
Pawel
  • 31,342
  • 4
  • 73
  • 104
  • Yeah, it seems this could do the trick, but I didnt find a way to instantiate system.data.metadata.edm.entitytype for particular entity. Its constructor is parameterless and there is also nothing among static methods. – Milos Mijatovic Apr 21 '12 at 06:32
  • I added some code showing how to do that. ctx in this case is DbContext. If you are not using CodeFirst you don't need the IObjectContextAdpater - MetadataWorkspace property will be directly on your context (derived from ObjectContext) – Pawel Apr 22 '12 at 06:02
  • Yes. 1st line, IObjectContextAdapter is for EF6, and cannot compile in vs2010,EF4. So I changed the 1st line as:NorthwindEntities en = new NorthwindEntities();var workspace = en.MetadataWorkspace;(Is it right?). Then run and in your 3rd line, exception:Sequence contains no matching element(I had replaced your MyEntity to Employee) – Lei Yang Dec 30 '13 at 01:46
  • you could use the following code: `foreach(var e in itemCollection.OfType()) { Console.WriteLine('{0}, {1}', e.FullName, itemCollection.GetClrType(e).FullName); }` to dump what entities you have and what are their corresponding clr types. This should give you a clue how you CLR types are mapped. – Pawel Dec 30 '13 at 03:28
  • itemCollection contains many basic types such as int,string,etc, but no type of EntityType. – Lei Yang Dec 30 '13 at 11:47
  • In that case it seems like your MetadataWorkspace is not loaded. You would need to show more code but I think you should create a new question since comments are not the right way to address it and it feels like it is a different issue from the one being discussed. Finally someone else can also jump in and try to answer. – Pawel Dec 30 '13 at 18:11
  • Pls check this:http://stackoverflow.com/questions/20823028/get-navigation-properties-of-given-entitytype – Lei Yang Dec 31 '13 at 07:24
3

You can use one more approach to solve the problem.

Obs: found variable is some DbContext entity instance;

foreach (var propertyInfo in found.GetType().GetProperties())
{
    var reference = Context.Entry(found).Member(propertyInfo.Name) as DbReferenceEntry;

    if (reference != null)
    {
        reference.Load();
    }
}
Marcos Dimitrio
  • 6,651
  • 5
  • 38
  • 62
GlTech
  • 31
  • 2
-1

Just as simple as :

if (context.Model.FindEntityType(propertyInfo.PropertyType) is not null)

Where:

  • context is an instance of you custom DbContext
  • propertyInfo is gained by typeof(entity class).GetPropertyInfo(property name)
  • 1
    Did you even try it ?! – zolfaqarimr Feb 16 '23 at 19:45
  • EF core has native methods to get navigation properties from mapped classes. Use those methods. Then you don't have to make assumptions based on reflection. – Gert Arnold Feb 17 '23 at 07:46
  • I wanted to remove the downvote, because after your revision the answer is more clear (although the method is still disputable IMO), but somehow Stack Overflow doesn't see it as edited, therefore the vote is locked. Could you try to edit it again? – Gert Arnold Feb 17 '23 at 10:30