private static bool IsCandidateNavigationProperty( InternalEntityTypeBuilder sourceEntityTypeBuilder, string navigationName, PropertyInfo propertyInfo) { if (propertyInfo == null) { return(false); } if (sourceEntityTypeBuilder == null || sourceEntityTypeBuilder.ModelBuilder.IsIgnored(sourceEntityTypeBuilder.Metadata.Name, ConfigurationSource.Convention)) { return(false); } if (sourceEntityTypeBuilder.IsIgnored(navigationName, ConfigurationSource.Convention)) { return(false); } if (sourceEntityTypeBuilder.Metadata.FindProperty(navigationName) != null) { return(false); } if (sourceEntityTypeBuilder.Metadata.FindServiceProperty(navigationName) != null) { return(false); } return(true); }
private IReadOnlyList <RelationshipCandidate> FindRelationshipCandidates(InternalEntityTypeBuilder entityTypeBuilder) { var relationshipCandidates = new Dictionary <Type, RelationshipCandidate>(); var navigationCandidates = GetNavigationCandidates(entityTypeBuilder.Metadata); foreach (var candidateTuple in navigationCandidates) { var navigationPropertyInfo = candidateTuple.Key; var targetClrType = candidateTuple.Value; if (entityTypeBuilder.IsIgnored(navigationPropertyInfo.Name, ConfigurationSource.Convention)) { continue; } var candidateTargetEntityTypeBuilder = entityTypeBuilder.ModelBuilder.Entity(targetClrType, ConfigurationSource.Convention); if (candidateTargetEntityTypeBuilder == null) { continue; } var entityType = entityTypeBuilder.Metadata; RelationshipCandidate existingCandidate; if (relationshipCandidates.TryGetValue(targetClrType, out existingCandidate)) { if (candidateTargetEntityTypeBuilder.Metadata != entityType || !existingCandidate.InverseProperties.Contains(navigationPropertyInfo)) { existingCandidate.NavigationProperties.Add(navigationPropertyInfo); } continue; } var navigations = new HashSet <PropertyInfo> { navigationPropertyInfo }; var inverseCandidates = GetNavigationCandidates(candidateTargetEntityTypeBuilder.Metadata); var inverseNavigationCandidates = new HashSet <PropertyInfo>(); foreach (var inverseCandidateTuple in inverseCandidates) { var inversePropertyInfo = inverseCandidateTuple.Key; var inverseTargetType = inverseCandidateTuple.Value; if (inverseTargetType != entityType.ClrType || Equals(navigationPropertyInfo, inversePropertyInfo) || candidateTargetEntityTypeBuilder.IsIgnored(inversePropertyInfo.Name, ConfigurationSource.Convention)) { continue; } inverseNavigationCandidates.Add(inversePropertyInfo); } relationshipCandidates[targetClrType] = new RelationshipCandidate(candidateTargetEntityTypeBuilder, navigations, inverseNavigationCandidates); } return(relationshipCandidates.Values.ToList()); }
public virtual bool Apply( InternalEntityTypeBuilder sourceEntityTypeBuilder, InternalEntityTypeBuilder targetEntityTypeBuilder, string navigationName) { sourceEntityTypeBuilder = sourceEntityTypeBuilder.Metadata.Builder; if (sourceEntityTypeBuilder == null || sourceEntityTypeBuilder.ModelBuilder.IsIgnored(sourceEntityTypeBuilder.Metadata.Name, ConfigurationSource.Convention)) { return(true); } if (sourceEntityTypeBuilder.IsIgnored(navigationName, ConfigurationSource.Convention)) { return(true); } Apply(sourceEntityTypeBuilder); foreach (var derivedType in sourceEntityTypeBuilder.Metadata.GetDerivedTypes()) { Apply(derivedType.Builder); } return(true); }
private IReadOnlyList <RelationshipCandidate> FindRelationshipCandidates(InternalEntityTypeBuilder entityTypeBuilder) { var entityType = entityTypeBuilder.Metadata; var relationshipCandidates = new Dictionary <Type, RelationshipCandidate>(); foreach (var navigationPropertyInfo in entityType.ClrType.GetRuntimeProperties().OrderBy(p => p.Name)) { var targetClrType = FindCandidateNavigationPropertyType(navigationPropertyInfo); var navigationName = navigationPropertyInfo.Name; if (targetClrType == null || entityTypeBuilder.IsIgnored(navigationName, configurationSource: ConfigurationSource.Convention)) { continue; } var candidateTargetEntityTypeBuilder = entityTypeBuilder.ModelBuilder.Entity(targetClrType, ConfigurationSource.Convention); if (candidateTargetEntityTypeBuilder == null) { continue; } RelationshipCandidate existingCandidate; if (relationshipCandidates.TryGetValue(candidateTargetEntityTypeBuilder.Metadata.ClrType, out existingCandidate)) { if (candidateTargetEntityTypeBuilder.Metadata != entityType || !existingCandidate.InverseProperties.Contains(navigationPropertyInfo)) { existingCandidate.NavigationProperties.Add(navigationPropertyInfo); } continue; } var navigations = new HashSet <PropertyInfo> { navigationPropertyInfo }; var inverseNavigationCandidates = new HashSet <PropertyInfo>(); foreach (var inversePropertyInfo in candidateTargetEntityTypeBuilder.Metadata.ClrType.GetRuntimeProperties().OrderBy(p => p.Name)) { var inverseTargetType = FindCandidateNavigationPropertyType(inversePropertyInfo); if (inverseTargetType == null || !inverseTargetType.GetTypeInfo().IsAssignableFrom(entityType.ClrType.GetTypeInfo()) || navigationPropertyInfo == inversePropertyInfo || candidateTargetEntityTypeBuilder.IsIgnored(inversePropertyInfo.Name, ConfigurationSource.Convention)) { continue; } inverseNavigationCandidates.Add(inversePropertyInfo); } relationshipCandidates[candidateTargetEntityTypeBuilder.Metadata.ClrType] = new RelationshipCandidate(candidateTargetEntityTypeBuilder, navigations, inverseNavigationCandidates); } return(relationshipCandidates.Values.ToList()); }
private static bool IsCandidateNavigationProperty( InternalEntityTypeBuilder sourceEntityTypeBuilder, string navigationName, MemberInfo propertyInfo) => propertyInfo != null && sourceEntityTypeBuilder != null && !sourceEntityTypeBuilder.IsIgnored(navigationName, ConfigurationSource.Convention) && sourceEntityTypeBuilder.Metadata.FindProperty(navigationName) == null && sourceEntityTypeBuilder.Metadata.FindServiceProperty(navigationName) == null && (!sourceEntityTypeBuilder.Metadata.IsQueryType || (propertyInfo as PropertyInfo)?.PropertyType.TryGetSequenceType() == null);
private IReadOnlyList<RelationshipCandidate> FindRelationshipCandidates(InternalEntityTypeBuilder entityTypeBuilder) { var entityType = entityTypeBuilder.Metadata; var relationshipCandidates = new Dictionary<Type, RelationshipCandidate>(); foreach (var navigationPropertyInfo in entityType.ClrType.GetRuntimeProperties().OrderBy(p => p.Name)) { var targetClrType = FindCandidateNavigationPropertyType(navigationPropertyInfo); var navigationName = navigationPropertyInfo.Name; if (targetClrType == null || entityTypeBuilder.IsIgnored(navigationName, configurationSource: ConfigurationSource.Convention)) { continue; } var candidateTargetEntityTypeBuilder = entityTypeBuilder.ModelBuilder.Entity(targetClrType, ConfigurationSource.Convention); if (candidateTargetEntityTypeBuilder == null) { continue; } RelationshipCandidate existingCandidate; if (relationshipCandidates.TryGetValue(candidateTargetEntityTypeBuilder.Metadata.ClrType, out existingCandidate)) { if (candidateTargetEntityTypeBuilder.Metadata != entityType || !existingCandidate.InverseProperties.Contains(navigationPropertyInfo)) { existingCandidate.NavigationProperties.Add(navigationPropertyInfo); } continue; } var navigations = new HashSet<PropertyInfo> { navigationPropertyInfo }; var inverseNavigationCandidates = new HashSet<PropertyInfo>(); foreach (var inversePropertyInfo in candidateTargetEntityTypeBuilder.Metadata.ClrType.GetRuntimeProperties().OrderBy(p => p.Name)) { var inverseTargetType = FindCandidateNavigationPropertyType(inversePropertyInfo); if (inverseTargetType == null || !inverseTargetType.GetTypeInfo().IsAssignableFrom(entityType.ClrType.GetTypeInfo()) || navigationPropertyInfo == inversePropertyInfo || candidateTargetEntityTypeBuilder.IsIgnored(inversePropertyInfo.Name, ConfigurationSource.Convention)) { continue; } inverseNavigationCandidates.Add(inversePropertyInfo); } relationshipCandidates[candidateTargetEntityTypeBuilder.Metadata.ClrType] = new RelationshipCandidate(candidateTargetEntityTypeBuilder, navigations, inverseNavigationCandidates); } return relationshipCandidates.Values.ToList(); }
/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public virtual bool Apply(InternalEntityTypeBuilder entityTypeBuilder, string ignoredMemberName) { var navigationCandidates = GetNavigationCandidates(entityTypeBuilder); var candidate = navigationCandidates.Keys.FirstOrDefault(p => p.Name == ignoredMemberName); if (candidate == null) { return(true); } navigationCandidates = navigationCandidates.Remove(candidate); SetNavigationCandidates(entityTypeBuilder, navigationCandidates); DiscoverRelationships(entityTypeBuilder); return(entityTypeBuilder.IsIgnored(ignoredMemberName, ConfigurationSource.Convention)); }
/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public virtual bool Apply( InternalEntityTypeBuilder sourceEntityTypeBuilder, InternalEntityTypeBuilder targetEntityTypeBuilder, string navigationName, PropertyInfo propertyInfo) { if (propertyInfo == null) { return(true); } sourceEntityTypeBuilder = sourceEntityTypeBuilder.Metadata.Builder; if (sourceEntityTypeBuilder == null || sourceEntityTypeBuilder.ModelBuilder.IsIgnored(sourceEntityTypeBuilder.Metadata.Name, ConfigurationSource.Convention)) { return(true); } if (sourceEntityTypeBuilder.IsIgnored(navigationName, ConfigurationSource.Convention)) { return(true); } foreach (var entityType in sourceEntityTypeBuilder.Metadata.GetDerivedTypesInclusive()) { if (entityType.FindNavigation(navigationName) != null) { continue; } var entityTypeBuilder = entityType.Builder; var navigationCandidates = GetNavigationCandidates(entityTypeBuilder); navigationCandidates = navigationCandidates.Add(propertyInfo, FindCandidateNavigationPropertyType(propertyInfo)); SetNavigationCandidates(entityTypeBuilder, navigationCandidates); DiscoverRelationships(entityTypeBuilder); } return(true); }
private IReadOnlyList <RelationshipCandidate> FindRelationshipCandidates(InternalEntityTypeBuilder entityTypeBuilder) { var relationshipCandidates = new Dictionary <EntityType, RelationshipCandidate>(); var navigationCandidates = GetNavigationCandidates(entityTypeBuilder.Metadata); foreach (var candidateTuple in navigationCandidates) { var navigationPropertyInfo = candidateTuple.Key; var targetClrType = candidateTuple.Value; if (entityTypeBuilder.IsIgnored(navigationPropertyInfo.Name, ConfigurationSource.Convention)) { continue; } InternalEntityTypeBuilder candidateTargetEntityTypeBuilder = null; if (!entityTypeBuilder.ModelBuilder.Metadata.IsDelegatedIdentityEntityType(targetClrType)) { candidateTargetEntityTypeBuilder = entityTypeBuilder.ModelBuilder.Entity(targetClrType, ConfigurationSource.Convention); } else if (!targetClrType.GetTypeInfo().Equals(entityTypeBuilder.Metadata.ClrType.GetTypeInfo()) && !entityTypeBuilder.Metadata.IsInDefinitionPath(targetClrType)) { candidateTargetEntityTypeBuilder = entityTypeBuilder.Metadata.FindNavigation(navigationPropertyInfo.Name)?.GetTargetType().Builder ?? entityTypeBuilder.ModelBuilder.Metadata.FindDelegatedIdentityEntityType( targetClrType, navigationPropertyInfo.Name, entityTypeBuilder.Metadata)?.Builder ?? entityTypeBuilder.ModelBuilder.AddDelegatedIdentityEntity( targetClrType, navigationPropertyInfo.Name, entityTypeBuilder.Metadata, ConfigurationSource.Convention); } if (candidateTargetEntityTypeBuilder == null) { continue; } var entityType = entityTypeBuilder.Metadata; if (relationshipCandidates.TryGetValue(candidateTargetEntityTypeBuilder.Metadata, out RelationshipCandidate existingCandidate)) { if (candidateTargetEntityTypeBuilder.Metadata != entityType || !existingCandidate.InverseProperties.Contains(navigationPropertyInfo)) { existingCandidate.NavigationProperties.Add(navigationPropertyInfo); } continue; } var navigations = new HashSet <PropertyInfo> { navigationPropertyInfo }; var inverseCandidates = GetNavigationCandidates(candidateTargetEntityTypeBuilder.Metadata); var inverseNavigationCandidates = new HashSet <PropertyInfo>(); foreach (var inverseCandidateTuple in inverseCandidates) { var inversePropertyInfo = inverseCandidateTuple.Key; var inverseTargetType = inverseCandidateTuple.Value; if (inverseTargetType != entityType.ClrType || navigationPropertyInfo.IsSameAs(inversePropertyInfo) || candidateTargetEntityTypeBuilder.IsIgnored(inversePropertyInfo.Name, ConfigurationSource.Convention)) { continue; } inverseNavigationCandidates.Add(inversePropertyInfo); } relationshipCandidates[candidateTargetEntityTypeBuilder.Metadata] = new RelationshipCandidate(candidateTargetEntityTypeBuilder, navigations, inverseNavigationCandidates); } return(relationshipCandidates.Values.ToList()); }
/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public virtual InternalEntityTypeBuilder Apply(InternalEntityTypeBuilder entityTypeBuilder) { Check.NotNull(entityTypeBuilder, nameof(entityTypeBuilder)); var entityType = entityTypeBuilder.Metadata; if (!entityType.HasClrType()) { return(entityTypeBuilder); } var candidates = entityType.GetRuntimeProperties().Values; foreach (var propertyInfo in candidates) { if (entityTypeBuilder.IsIgnored(propertyInfo.Name, ConfigurationSource.Convention) || entityType.FindProperty(propertyInfo) != null || entityType.FindNavigation(propertyInfo) != null || !propertyInfo.IsCandidateProperty(publicOnly: false) || (propertyInfo.IsCandidateProperty() && _typeMappingSource.FindMapping(propertyInfo) != null)) { continue; } var factory = _parameterBindingFactories.FindFactory(propertyInfo.PropertyType, propertyInfo.Name); if (factory == null) { continue; } var duplicateMap = GetDuplicateServiceProperties(entityType); if (duplicateMap != null && duplicateMap.TryGetValue(propertyInfo.PropertyType, out var duplicateServiceProperties)) { duplicateServiceProperties.Add(propertyInfo); return(entityTypeBuilder); } var otherServicePropertySameType = entityType.GetServiceProperties() .FirstOrDefault(p => p.ClrType == propertyInfo.PropertyType); if (otherServicePropertySameType != null) { if (ConfigurationSource.Convention.Overrides(otherServicePropertySameType.GetConfigurationSource())) { otherServicePropertySameType.DeclaringEntityType.RemoveServiceProperty(otherServicePropertySameType.Name); } AddDuplicateServiceProperty(entityTypeBuilder, propertyInfo); AddDuplicateServiceProperty(entityTypeBuilder, otherServicePropertySameType.GetIdentifyingMemberInfo()); return(entityTypeBuilder); } entityTypeBuilder.ServiceProperty(propertyInfo, ConfigurationSource.Convention)?.SetParameterBinding( (ServiceParameterBinding)factory.Bind(entityType, propertyInfo.PropertyType, propertyInfo.Name), ConfigurationSource.Convention); } return(entityTypeBuilder); }
private IReadOnlyList <RelationshipCandidate> FindRelationshipCandidates(InternalEntityTypeBuilder entityTypeBuilder) { var relationshipCandidates = new Dictionary <EntityType, RelationshipCandidate>(); var navigationCandidates = GetNavigationCandidates(entityTypeBuilder.Metadata); foreach (var candidateTuple in navigationCandidates) { var navigationPropertyInfo = candidateTuple.Key; var targetClrType = candidateTuple.Value; if (entityTypeBuilder.IsIgnored(navigationPropertyInfo.Name, ConfigurationSource.Convention) || (entityTypeBuilder.Metadata.IsQueryType && navigationPropertyInfo.PropertyType.TryGetSequenceType() != null)) { continue; } InternalEntityTypeBuilder candidateTargetEntityTypeBuilder = null; if (!entityTypeBuilder.ModelBuilder.Metadata.HasEntityTypeWithDefiningNavigation(targetClrType)) { candidateTargetEntityTypeBuilder = entityTypeBuilder.ModelBuilder.Entity(targetClrType, ConfigurationSource.Convention); } else if (!targetClrType.GetTypeInfo().Equals(entityTypeBuilder.Metadata.ClrType.GetTypeInfo()) && !entityTypeBuilder.Metadata.IsInDefinitionPath(targetClrType)) { candidateTargetEntityTypeBuilder = entityTypeBuilder.Metadata.FindNavigation(navigationPropertyInfo.Name)?.GetTargetType().Builder ?? entityTypeBuilder.ModelBuilder.Metadata.FindEntityType( targetClrType, navigationPropertyInfo.Name, entityTypeBuilder.Metadata)?.Builder ?? entityTypeBuilder.ModelBuilder.Entity( targetClrType, navigationPropertyInfo.Name, entityTypeBuilder.Metadata, ConfigurationSource.Convention); } if (candidateTargetEntityTypeBuilder == null || (entityTypeBuilder.ModelBuilder.Metadata.ShouldBeOwnedType(entityTypeBuilder.Metadata.ClrType) && candidateTargetEntityTypeBuilder.Metadata == entityTypeBuilder.Metadata)) { continue; } var candidateTargetEntityType = candidateTargetEntityTypeBuilder.Metadata; if (candidateTargetEntityType.IsQueryType) { continue; } if (!entityTypeBuilder.Metadata.Model.ShouldBeOwnedType(candidateTargetEntityType.ClrType)) { var ownership = candidateTargetEntityType.FindOwnership(); if (ownership != null && ownership.PrincipalEntityType != entityTypeBuilder.Metadata) { var inverseOwnership = entityTypeBuilder.Metadata.FindOwnership(); if (inverseOwnership == null || inverseOwnership.PrincipalEntityType != candidateTargetEntityType) { continue; } } } var entityType = entityTypeBuilder.Metadata; if (relationshipCandidates.TryGetValue(candidateTargetEntityType, out var existingCandidate)) { if (candidateTargetEntityType != entityType || !existingCandidate.InverseProperties.Contains(navigationPropertyInfo)) { existingCandidate.NavigationProperties.Add(navigationPropertyInfo); } continue; } var navigations = new HashSet <PropertyInfo> { navigationPropertyInfo }; var inverseCandidates = GetNavigationCandidates(candidateTargetEntityType); var inverseNavigationCandidates = new HashSet <PropertyInfo>(); foreach (var inverseCandidateTuple in inverseCandidates) { var inversePropertyInfo = inverseCandidateTuple.Key; var inverseTargetType = inverseCandidateTuple.Value; if (inverseTargetType != entityType.ClrType || navigationPropertyInfo.IsSameAs(inversePropertyInfo) || candidateTargetEntityTypeBuilder.IsIgnored(inversePropertyInfo.Name, ConfigurationSource.Convention) || entityType.IsQueryType || (entityType.HasDefiningNavigation() && entityType.DefiningEntityType == candidateTargetEntityType && entityType.DefiningNavigationName != inversePropertyInfo.Name)) { continue; } inverseNavigationCandidates.Add(inversePropertyInfo); } relationshipCandidates[candidateTargetEntityType] = new RelationshipCandidate(candidateTargetEntityTypeBuilder, navigations, inverseNavigationCandidates); } return(relationshipCandidates.Values.ToList()); }
public virtual bool Apply( InternalEntityTypeBuilder sourceEntityTypeBuilder, InternalEntityTypeBuilder targetEntityTypeBuilder, string navigationName) { if (sourceEntityTypeBuilder.IsIgnored(navigationName, ConfigurationSource.Convention)) { return true; } Apply(sourceEntityTypeBuilder); foreach (var derivedType in sourceEntityTypeBuilder.Metadata.GetDerivedTypes()) { Apply(sourceEntityTypeBuilder.ModelBuilder.Entity(derivedType.Name, ConfigurationSource.Convention)); } return true; }