Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RevEng: Use unbound NavProps on the IModel instead of annotations #5432

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,5 @@ public static ScaffoldingModelAnnotations Scaffolding([NotNull] this IModel mode

public static ScaffoldingPropertyAnnotations Scaffolding([NotNull] this IProperty property)
=> new ScaffoldingPropertyAnnotations(Check.NotNull(property, nameof(property)));

public static ScaffoldingForeignKeyAnnotations Scaffolding([NotNull] this IForeignKey foreignKey)
=> new ScaffoldingForeignKeyAnnotations(Check.NotNull(foreignKey, nameof(foreignKey)));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@
<Compile Include="Metadata\IndexModel.cs" />
<Compile Include="Metadata\Internal\ScaffoldingAnnotationNames.cs" />
<Compile Include="Metadata\Internal\ScaffoldingFullAnnotationNames.cs" />
<Compile Include="Metadata\ScaffoldingForeignKeyAnnotations.cs" />
<Compile Include="Metadata\ScaffoldingMetadataExtensions.cs" />
<Compile Include="Metadata\ScaffoldingModelAnnotations.cs" />
<Compile Include="Metadata\ScaffoldingPropertyAnnotations.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,6 @@ protected virtual ModelBuilder VisitDatabaseModel([NotNull] ModelBuilder modelBu
VisitSequences(modelBuilder, databaseModel.Sequences);
VisitTables(modelBuilder, databaseModel.Tables);
VisitForeignKeys(modelBuilder, databaseModel.Tables.SelectMany(table => table.ForeignKeys).ToList());
// TODO can we add navigation properties inline with adding foreign keys?
VisitNavigationProperties(modelBuilder);

return modelBuilder;
}
Expand Down Expand Up @@ -451,6 +449,14 @@ protected virtual ModelBuilder VisitForeignKeys([NotNull] ModelBuilder modelBuil
VisitForeignKey(modelBuilder, fk);
}

// Note: must completely assign all foreign keys before assigning
// navigation properties otherwise naming of navigation properties
// when there are multiple foreign keys does not work.
foreach (var foreignKey in modelBuilder.Model.GetEntityTypes().SelectMany(et => et.GetForeignKeys()))
{
AddNavigationProperties(foreignKey);
}

return modelBuilder;
}

Expand Down Expand Up @@ -559,59 +565,56 @@ protected virtual IMutableForeignKey VisitForeignKey([NotNull] ModelBuilder mode
return key;
}

protected virtual void VisitNavigationProperties([NotNull] ModelBuilder modelBuilder)
protected virtual void AddNavigationProperties([NotNull] IMutableForeignKey foreignKey)
{
Check.NotNull(modelBuilder, nameof(modelBuilder));
Check.NotNull(foreignKey, nameof(foreignKey));

// TODO perf cleanup can we do this in 1 loop instead of 2?
var model = modelBuilder.Model;
var modelUtilities = new ModelUtilities();
var dependentEndExistingIdentifiers = ExistingIdentifiers(foreignKey.DeclaringEntityType);
var dependentEndNavigationPropertyCandidateName =
modelUtilities.GetDependentEndCandidateNavigationPropertyName(foreignKey);
var dependentEndNavigationPropertyName =
CSharpUtilities.Instance.GenerateCSharpIdentifier(
dependentEndNavigationPropertyCandidateName,
dependentEndExistingIdentifiers,
NavigationUniquifier);

foreignKey.HasDependentToPrincipal(dependentEndNavigationPropertyName);

var principalEndExistingIdentifiers = ExistingIdentifiers(foreignKey.PrincipalEntityType);
var principalEndNavigationPropertyCandidateName = foreignKey.IsSelfReferencing()
? string.Format(
CultureInfo.CurrentCulture,
SelfReferencingPrincipalEndNavigationNamePattern,
dependentEndNavigationPropertyName)
: modelUtilities.GetPrincipalEndCandidateNavigationPropertyName(
foreignKey, dependentEndNavigationPropertyName);
var principalEndNavigationPropertyName =
CSharpUtilities.Instance.GenerateCSharpIdentifier(
principalEndNavigationPropertyCandidateName,
principalEndExistingIdentifiers,
NavigationUniquifier);

foreignKey.HasPrincipalToDependent(principalEndNavigationPropertyName);
}

var entityTypeToExistingIdentifiers = new Dictionary<IEntityType, List<string>>();
foreach (var entityType in model.GetEntityTypes())
// Stores the names of the EntityType itself and its Properties, but does not include any Navigation Properties
private Dictionary<IEntityType, List<string>> _entityTypeAndPropertyIdentifiers = new Dictionary<IEntityType, List<string>>();
protected virtual List<string> ExistingIdentifiers([NotNull] IEntityType entityType)
{
Check.NotNull(entityType, nameof(entityType));

List<string> existingIdentifiers;
if (!_entityTypeAndPropertyIdentifiers.TryGetValue(entityType, out existingIdentifiers))
{
var existingIdentifiers = new List<string>();
entityTypeToExistingIdentifiers.Add(entityType, existingIdentifiers);
existingIdentifiers = new List<string>();
existingIdentifiers.Add(entityType.Name);
existingIdentifiers.AddRange(entityType.GetProperties().Select(p => p.Name));
_entityTypeAndPropertyIdentifiers[entityType] = existingIdentifiers;
}

foreach (var entityType in model.GetEntityTypes())
{
var dependentEndExistingIdentifiers = entityTypeToExistingIdentifiers[entityType];
foreach (var foreignKey in entityType.GetForeignKeys())
{
// set up the name of the navigation property on the dependent end of the foreign key
var dependentEndNavigationPropertyCandidateName =
modelUtilities.GetDependentEndCandidateNavigationPropertyName(foreignKey);
var dependentEndNavigationPropertyName =
CSharpUtilities.Instance.GenerateCSharpIdentifier(
dependentEndNavigationPropertyCandidateName,
dependentEndExistingIdentifiers,
NavigationUniquifier);
foreignKey.Scaffolding().DependentEndNavigation = dependentEndNavigationPropertyName;
dependentEndExistingIdentifiers.Add(dependentEndNavigationPropertyName);

// set up the name of the navigation property on the principal end of the foreign key
var principalEndExistingIdentifiers =
entityTypeToExistingIdentifiers[foreignKey.PrincipalEntityType];
var principalEndNavigationPropertyCandidateName =
foreignKey.IsSelfReferencing()
? string.Format(
CultureInfo.CurrentCulture,
SelfReferencingPrincipalEndNavigationNamePattern,
dependentEndNavigationPropertyName)
: modelUtilities.GetPrincipalEndCandidateNavigationPropertyName(
foreignKey, dependentEndNavigationPropertyName);
var principalEndNavigationPropertyName =
CSharpUtilities.Instance.GenerateCSharpIdentifier(
principalEndNavigationPropertyCandidateName,
principalEndExistingIdentifiers,
NavigationUniquifier);
foreignKey.Scaffolding().PrincipalEndNavigation = principalEndNavigationPropertyName;
principalEndExistingIdentifiers.Add(principalEndNavigationPropertyName);
}
}
existingIdentifiers.AddRange(entityType.GetNavigations().Select(p => p.Name));
return existingIdentifiers;
}

private static void AssignOnDeleteAction(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -573,79 +573,79 @@ public virtual void AddNavigationProperties([NotNull] EntityConfiguration entity
foreach (var foreignKey in otherEntityType
.GetForeignKeys().Where(fk => fk.PrincipalEntityType == entityConfiguration.EntityType))
{
var referencedType = foreignKey.IsUnique
? otherEntityType.Name
: "ICollection<" + otherEntityType.Name + ">";
var navPropConfiguration =
_configurationFactory.CreateNavigationPropertyConfiguration(
referencedType,
foreignKey.Scaffolding().PrincipalEndNavigation);

if (foreignKey.PrincipalKey.IsPrimaryKey())
var principalNavProp = foreignKey.PrincipalToDependent;
if (principalNavProp != null)
{
navPropConfiguration.AttributeConfigurations.Add(
_configurationFactory.CreateAttributeConfiguration(
nameof(InversePropertyAttribute),
CSharpUtilities.DelimitString(
foreignKey.Scaffolding().DependentEndNavigation)));
var referencedType = foreignKey.IsUnique
? otherEntityType.Name
: "ICollection<" + otherEntityType.Name + ">";
var navPropConfiguration =
_configurationFactory.CreateNavigationPropertyConfiguration(
referencedType, principalNavProp.Name);

var dependentNavProp = foreignKey.DependentToPrincipal;
if (foreignKey.PrincipalKey.IsPrimaryKey() &&
dependentNavProp != null)
{
navPropConfiguration.AttributeConfigurations.Add(
_configurationFactory.CreateAttributeConfiguration(
nameof(InversePropertyAttribute),
CSharpUtilities.DelimitString(dependentNavProp.Name)));
}

entityConfiguration.NavigationPropertyConfigurations.Add(navPropConfiguration);
}

entityConfiguration.NavigationPropertyConfigurations.Add(navPropConfiguration);
}
}

foreach (var foreignKey in entityConfiguration.EntityType.GetForeignKeys())
{
// set up the navigation property on this end of foreign keys owned by this EntityType
// (i.e. this EntityType is the dependent)
var dependentEndNavPropConfiguration =
_configurationFactory.CreateNavigationPropertyConfiguration(
foreignKey.PrincipalEntityType.Name,
foreignKey.Scaffolding().DependentEndNavigation);

if (foreignKey.PrincipalKey.IsPrimaryKey())
var dependentNavProp = foreignKey.DependentToPrincipal;
if (dependentNavProp != null)
{
dependentEndNavPropConfiguration.AttributeConfigurations.Add(
_configurationFactory.CreateAttributeConfiguration(
nameof(ForeignKeyAttribute),
CSharpUtilities.DelimitString(
string.Join(",", foreignKey.Properties.Select(p => p.Name)))));
dependentEndNavPropConfiguration.AttributeConfigurations.Add(
_configurationFactory.CreateAttributeConfiguration(
nameof(InversePropertyAttribute),
CSharpUtilities.DelimitString(
foreignKey.Scaffolding().PrincipalEndNavigation)));
}
var dependentEndNavPropConfiguration =
_configurationFactory.CreateNavigationPropertyConfiguration(
foreignKey.PrincipalEntityType.Name, dependentNavProp.Name);

entityConfiguration.NavigationPropertyConfigurations.Add(
dependentEndNavPropConfiguration);
var principalNavProp = foreignKey.PrincipalToDependent;
if (foreignKey.PrincipalKey.IsPrimaryKey() && principalNavProp != null)
{
dependentEndNavPropConfiguration.AttributeConfigurations.Add(
_configurationFactory.CreateAttributeConfiguration(
nameof(ForeignKeyAttribute),
CSharpUtilities.DelimitString(
string.Join(",", foreignKey.Properties.Select(p => p.Name)))));
dependentEndNavPropConfiguration.AttributeConfigurations.Add(
_configurationFactory.CreateAttributeConfiguration(
nameof(InversePropertyAttribute),
CSharpUtilities.DelimitString(principalNavProp.Name)));
}

// set up the other navigation property for self-referencing foreign keys owned by this EntityType
if (((ForeignKey)foreignKey).IsSelfReferencing())
{
var referencedType = foreignKey.IsUnique
? foreignKey.DeclaringEntityType.Name
: "ICollection<" + foreignKey.DeclaringEntityType.Name + ">";
var principalEndNavPropConfiguration =
_configurationFactory.CreateNavigationPropertyConfiguration(
referencedType,
foreignKey.Scaffolding().PrincipalEndNavigation);
principalEndNavPropConfiguration.AttributeConfigurations.Add(
_configurationFactory.CreateAttributeConfiguration(
nameof(InversePropertyAttribute),
CSharpUtilities.DelimitString(
foreignKey.Scaffolding().DependentEndNavigation)));
entityConfiguration.NavigationPropertyConfigurations.Add(
principalEndNavPropConfiguration);
dependentEndNavPropConfiguration);

// set up the other navigation property for self-referencing foreign keys owned by this EntityType
if (((ForeignKey)foreignKey).IsSelfReferencing() && principalNavProp != null)
{
var referencedType = foreignKey.IsUnique
? foreignKey.DeclaringEntityType.Name
: "ICollection<" + foreignKey.DeclaringEntityType.Name + ">";
var principalEndNavPropConfiguration =
_configurationFactory.CreateNavigationPropertyConfiguration(
referencedType, principalNavProp.Name);
principalEndNavPropConfiguration.AttributeConfigurations.Add(
_configurationFactory.CreateAttributeConfiguration(
nameof(InversePropertyAttribute),
CSharpUtilities.DelimitString(dependentNavProp.Name)));
entityConfiguration.NavigationPropertyConfigurations.Add(
principalEndNavPropConfiguration);
}
}
}
}

public virtual void AddNavigationPropertyConfiguration(
[NotNull] NavigationPropertyConfiguration navigationPropertyConfiguration)
{
}

public virtual void AddNavigationPropertyInitializers([NotNull] EntityConfiguration entityConfiguration)
{
Check.NotNull(entityConfiguration, nameof(entityConfiguration));
Expand All @@ -656,13 +656,12 @@ public virtual void AddNavigationPropertyInitializers([NotNull] EntityConfigurat
foreach (var foreignKey in otherEntityType
.GetForeignKeys().Where(fk => fk.PrincipalEntityType == entityConfiguration.EntityType))
{
var navigationPropertyName =
foreignKey.Scaffolding().PrincipalEndNavigation;
if (!foreignKey.IsUnique)
var navigationProperty = foreignKey.PrincipalToDependent;
if (!foreignKey.IsUnique && navigationProperty != null)
{
entityConfiguration.NavigationPropertyInitializerConfigurations.Add(
_configurationFactory.CreateNavigationPropertyInitializerConfiguration(
navigationPropertyName, otherEntityType.Name));
navigationProperty.Name, otherEntityType.Name));
}
}
}
Expand All @@ -674,10 +673,8 @@ public virtual void AddRelationshipConfiguration([NotNull] EntityConfiguration e

foreach (var foreignKey in entityConfiguration.EntityType.GetForeignKeys())
{
var dependentEndNavigationPropertyName =
foreignKey.Scaffolding().DependentEndNavigation;
var principalEndNavigationPropertyName =
foreignKey.Scaffolding().PrincipalEndNavigation;
var dependentEndNavigationPropertyName = foreignKey.DependentToPrincipal.Name;
var principalEndNavigationPropertyName = foreignKey.PrincipalToDependent.Name;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

null check for navigations needed?

Copy link
Contributor Author

@lajones lajones May 23, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@smitpatel Will do. After that can I convert the LGTM to a ship-it?


var relationshipConfiguration = _configurationFactory
.CreateRelationshipConfiguration(
Expand Down
Loading