// attaches the navigation property of a child back to its parent (if exists) public static void AttachCyclicNavigationProperty(DbContext db, object parent, object child) { if (parent == null || child == null) { return; } var parentType = ObjectContext.GetObjectType(parent.GetType()); var childType = ObjectContext.GetObjectType(child.GetType()); var objectContext = ((System.Data.Entity.Infrastructure.IObjectContextAdapter)db).ObjectContext; MethodInfo m = objectContext.GetType().GetMethod("CreateObjectSet", new Type[] { }); MethodInfo generic = m.MakeGenericMethod(childType); object set = generic.Invoke(objectContext, null); PropertyInfo entitySetPI = set.GetType().GetProperty("EntitySet"); System.Data.Metadata.Edm.EntitySet entitySet = (System.Data.Metadata.Edm.EntitySet)entitySetPI.GetValue(set, null); foreach (var prop in entitySet.ElementType.NavigationProperties) { if (prop.TypeUsage.EdmType.Name == parentType.Name) { var propInfo = childType.GetProperty(prop.Name); propInfo.SetValue(child, parent, null); break; } } }
// Gets the primary key fields for an entity type. public static IEnumerable <PropertyInfo> GetKeysFor(this DbContext db, Type entityType) { var objectContext = ((System.Data.Entity.Infrastructure.IObjectContextAdapter)db).ObjectContext; MethodInfo m = objectContext.GetType().GetMethod("CreateObjectSet", new Type[] { }); MethodInfo generic = m.MakeGenericMethod(entityType); object set = generic.Invoke(objectContext, null); PropertyInfo entitySetPI = set.GetType().GetProperty("EntitySet"); System.Data.Metadata.Edm.EntitySet entitySet = (System.Data.Metadata.Edm.EntitySet)entitySetPI.GetValue(set, null); foreach (string name in entitySet.ElementType.KeyMembers.Select(k => k.Name)) { yield return(entityType.GetProperty(name)); } }