private static void SetDependencies(DbContext dbContext, GraphDependency graphDependency, object graphEntity, INavigation navigation, object navigationValue, IDictionary <object, GraphDependency> result) { // Get the nested dependency for the navigationValue so we can add the inverse navigation dependency // incase the navigationValue entity does not have an explicitly defined navigation property back to its principal / dependent // i.e WorkOrderSpare.Spare but the Spare entity does not have a Spare.WorkOrderSpares navigation property var nestedDependency = GetFlatGraph(dbContext, navigationValue, result); if (nestedDependency is null) { return; } if (navigation.IsOnDependent // A navigation for an OwnedType will be dependent on its owner the in efcore dependency hierarchy, // but technically the Owner depends on the OwnedType if the OwnedType is part of its Owner's schema. || OwnedTypeUtil.IsOwnedInSameTableAsOwner(navigation)) { graphDependency.DependsOn.Add((navigationValue, navigation)); nestedDependency.Dependents.Add((graphEntity, navigation.Inverse ?? navigation)); } else { graphDependency.Dependents.Add((navigationValue, navigation)); nestedDependency.DependsOn.Add((graphEntity, navigation.Inverse ?? navigation)); } }
private static GraphDependency GetFlatGraph(DbContext dbContext, object graphEntity, IDictionary <object, GraphDependency> result) { var entityType = dbContext.Model.FindEntityType(graphEntity.GetType()); // The entity is not being apart of the DbContext model, do nothing if (entityType is null) { return(null); } GraphDependency graphDependency; if (!result.TryGetValue(graphEntity, out graphDependency)) { graphDependency = new GraphDependency(); result.Add(graphEntity, graphDependency); } else { // To prevent circular references & stack overflow, if the graphEntity has already been tracked then just return return(graphDependency); } var entityNavigations = entityType.GetNavigations(); foreach (var navigation in entityNavigations) { if (navigation.IsCollection) { var navigationValue = dbContext.Entry(graphEntity).Collection(navigation.Name).CurrentValue; if (navigationValue is null) { continue; } var navigationCollectionValue = navigationValue.Cast <object>().ToList(); foreach (var navEntity in navigationCollectionValue) { SetDependencies(dbContext, graphDependency, graphEntity, navigation, navEntity, result); } } else { var navigationValue = dbContext.Entry(graphEntity).Reference(navigation.Name).CurrentValue; if (navigationValue is null) { continue; } SetDependencies(dbContext, graphDependency, graphEntity, navigation, navigationValue, result); } } return(graphDependency); }
private static void SetDependencies(DbContext dbContext, GraphDependency graphDependency, object graphEntity, INavigation navigation, object navigationValue, IDictionary <object, GraphDependency> result) { // Get the nested dependency for the navigationValue so we can add the inverse navigation dependency // incase the navigationValue entity does not have an explicitly defined navigation property back to its principal / dependent // i.e WorkOrderSpare.Spare but the Spare entity does not have a Spare.WorkOrderSpares navigation property var nestedDependency = GetFlatGraph(dbContext, navigationValue, result); if (navigation.IsOnDependent) { graphDependency.DependsOn.Add((navigationValue, navigation)); nestedDependency.Dependents.Add((graphEntity, navigation.Inverse ?? navigation)); } else { graphDependency.Dependents.Add((navigationValue, navigation)); nestedDependency.DependsOn.Add((graphEntity, navigation.Inverse ?? navigation)); } }