How to get foreign key value for independent association without hitting database?

I am using independent associations (with lazy loading) to access related entities in my code first model e.g.

public class Aaa {
  public int AaaId {get;set;}
  public string SomeValue {get;set;}
}

public class Bbb {
  public int BbbId {get;set;}
  public string SomeValue {get;set;}
  public virtual Aaa MyIndependentAssociation {get;set;}
}

but I am wondering how to access the foreign key value of MyIndependentAssociation without actually loading the record.

I am assuming the Aaa_AaaId value is actually loaded when I retrieve a Bbb entity from the database (according the debug visualizer on the entity table anyway).

How do I get access to the value (other than adding a Foreign Key association into my model)?

Answers


It's possible. With your example model you can find the foreign key values the following way:

Bbb bbb = myDbContext.Bbbs.First();

var objectContext = ((IObjectContextAdapter)myDbContext).ObjectContext;

var relMgr = objectContext.ObjectStateManager.GetRelationshipManager(bbb);
var relEnds = relMgr.GetAllRelatedEnds();
var relEnd = relEnds.Single(); // because yor model has exactly one relationship
var entityRef = relEnd as EntityReference<Aaa>;    
var entityKey = entityRef.EntityKey;

int foreignKeyValue = (int)entityKey.EntityKeyValues[0].Value;

// to confirm that no database query happened
Console.WriteLine(entityRef.IsLoaded); // outputs false

In the more general case where you have multiple relationships in the Bbb class and maybe even more than one navigation property refering to Aaa you need to find the correct element in the relEnds enumeration. You could also have composite foreign keys. It would look like this then:

Bbb bbb = myDbContext.Bbbs.First();

var objectContext = ((IObjectContextAdapter)myDbContext).ObjectContext;

var relMgr = objectContext.ObjectStateManager.GetRelationshipManager(bbb);
var entityRef = relMgr.GetRelatedReference<Aaa>(
    "MyEntityNamespace.Bbb_MyIndependentAssociation",
    "Bbb_MyIndependentAssociation_Target");
var entityKey = entityRef.EntityKey;

object[] compositeForeignKeyValues =
    entityKey.EntityKeyValues.Select(e => e.Value).ToArray();

// to confirm that no database query happened
Console.WriteLine(entityRef.IsLoaded); // outputs false

Note, that IsLoaded can be true if you inspect the entityRef object in the debugger which can cause the related object to be loaded (even though lazy loading is disabled).


Need Your Help

Method to Allow User to Select Multiple Items - ASP.Net MVC

asp.net-mvc multi-select

I have an e-commerce system that allows a product to have multiple categories. In the admin user interface, I'm going to allow the administrator to be able to add as many categories to the product ...

Turn orderBy filter into a directive

javascript angularjs

I have a frequent pattern in my app and I am curious if it is possible to solve it through a custom directive: