private static bool IsIdentifyingPrincipal(IEntityType dependEntityType, IEntityType principalEntityType) { var identifyingForeignKeys = new Queue <IForeignKey>( dependEntityType.FindForeignKeys(dependEntityType.FindPrimaryKey().Properties)); while (identifyingForeignKeys.Count > 0) { var fk = identifyingForeignKeys.Dequeue(); if (fk.PrincipalKey.IsPrimaryKey()) { if (fk.PrincipalEntityType == principalEntityType) { if (principalEntityType.BaseType != null) { // #8973 throw new InvalidOperationException( RelationalStrings.IncompatibleTableDerivedPrincipal( dependEntityType.Relational().TableName, dependEntityType.DisplayName(), principalEntityType.DisplayName(), principalEntityType.RootType().DisplayName())); } return(true); } foreach (var principalFk in fk.PrincipalEntityType.FindForeignKeys(fk.PrincipalEntityType.FindPrimaryKey().Properties)) { identifyingForeignKeys.Enqueue(principalFk); } } } return(false); }
private static bool IsIdentifyingPrincipal(IEntityType dependEntityType, IEntityType principalEntityType) { foreach (var foreignKey in dependEntityType.FindForeignKeys(dependEntityType.FindPrimaryKey().Properties)) { if (!foreignKey.PrincipalKey.IsPrimaryKey() || foreignKey.PrincipalEntityType != principalEntityType) { continue; } if (principalEntityType.BaseType != null) { // #8973 throw new InvalidOperationException( RelationalStrings.IncompatibleTableDerivedPrincipal( dependEntityType.Relational().TableName, dependEntityType.DisplayName(), principalEntityType.DisplayName(), principalEntityType.RootType().DisplayName())); } return(true); } return(false); }
private static bool IsIdentifyingPrincipal(IEntityType dependentEntityType, IEntityType principalEntityType) { return dependentEntityType.FindForeignKeys(dependentEntityType.FindPrimaryKey().Properties) .Any( fk => fk.PrincipalKey.IsPrimaryKey() && fk.PrincipalEntityType == principalEntityType); }
private static Expression GenerateSharedTableExpression( IEntityType entityType, HashSet <IEntityType> sharingTypes, SelectExpression selectExpression, IQuerySource querySource) { if (sharingTypes.Count == 1 || !entityType.FindForeignKeys(entityType.FindPrimaryKey().Properties) .Any(fk => fk.PrincipalKey.IsPrimaryKey() && fk.PrincipalEntityType != entityType && sharingTypes.Contains(fk.PrincipalEntityType))) { return(null); } var requiredNonPkProperties = entityType.GetProperties().Where(p => !p.IsNullable && !p.IsPrimaryKey()).ToList(); if (requiredNonPkProperties.Count > 0) { var discriminatorPredicate = IsNotNull(requiredNonPkProperties[0], selectExpression, querySource); if (requiredNonPkProperties.Count > 1) { discriminatorPredicate = requiredNonPkProperties .Skip(1) .Aggregate( discriminatorPredicate, (current, property) => Expression.AndAlso( IsNotNull(property, selectExpression, querySource), current)); } return(discriminatorPredicate); } else { var allNonPkProperties = entityType.GetProperties().Where(p => !p.IsPrimaryKey()).ToList(); if (allNonPkProperties.Count == 0) { return(null); } var discriminatorPredicate = IsNotNull(allNonPkProperties[0], selectExpression, querySource); if (allNonPkProperties.Count > 1) { discriminatorPredicate = allNonPkProperties .Skip(1) .Aggregate( discriminatorPredicate, (current, property) => Expression.OrElse( IsNotNull(property, selectExpression, querySource), current)); } return(discriminatorPredicate); } }
private void FindPaths(IEntityType entityType, HashSet <IEntityType> sharedTypes, Stack <IEntityType> currentPath, List <List <IEntityType> > result) { var identifyingFks = entityType.FindForeignKeys(entityType.FindPrimaryKey().Properties) .Where(fk => fk.PrincipalKey.IsPrimaryKey() && fk.PrincipalEntityType != entityType && sharedTypes.Contains(fk.PrincipalEntityType)) .ToList(); if (identifyingFks.Count == 0) { result.Add(new List <IEntityType>(currentPath)); return; } foreach (var fk in identifyingFks) { currentPath.Push(fk.PrincipalEntityType); FindPaths(fk.PrincipalEntityType.RootType(), sharedTypes, currentPath, result); currentPath.Pop(); } }
/// <summary> /// Gets the foreign keys defined on the given property. Only foreign keys that are defined on exactly the specified /// property are returned. Composite foreign keys that include the specified property are not returned. /// </summary> /// <param name="entityType"> The entity type to find the foreign keys on. </param> /// <param name="property"> The property to find the foreign keys on. </param> /// <returns> The foreign keys. </returns> public static IEnumerable <IForeignKey> FindForeignKeys([NotNull] this IEntityType entityType, [NotNull] IProperty property) => entityType.FindForeignKeys(new[] { property });