Skip to content

Commit

Permalink
Use shared-type entity types instead of entity types with defining na…
Browse files Browse the repository at this point in the history
…vigation.

They should behave mostly the same, except that DefiningEntityType and DefiningNavigationName will return true and Name will return what FullName returned previously

Fixes #22378
  • Loading branch information
AndriySvyryd committed Dec 7, 2020
1 parent ae4728a commit fd9155f
Show file tree
Hide file tree
Showing 84 changed files with 1,375 additions and 2,180 deletions.
19 changes: 12 additions & 7 deletions src/EFCore.Design/Migrations/Design/CSharpSnapshotGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -121,17 +121,15 @@ protected virtual void GenerateEntityTypes(
Check.NotNull(stringBuilder, nameof(stringBuilder));

foreach (var entityType in entityTypes.Where(
e => !e.HasDefiningNavigation()
&& e.FindOwnership() == null))
e => e.FindOwnership() == null))
{
stringBuilder.AppendLine();

GenerateEntityType(builderName, entityType, stringBuilder);
}

foreach (var entityType in entityTypes.Where(
e => !e.HasDefiningNavigation()
&& e.FindOwnership() == null
e => e.FindOwnership() == null
&& (e.GetDeclaredForeignKeys().Any()
|| e.GetDeclaredReferencingForeignKeys().Any(fk => fk.IsOwnership))))
{
Expand All @@ -141,8 +139,7 @@ protected virtual void GenerateEntityTypes(
}

foreach (var entityType in entityTypes.Where(
e => !e.HasDefiningNavigation()
&& e.FindOwnership() == null
e => e.FindOwnership() == null
&& e.GetDeclaredNavigations().Any(n => !n.IsOnDependent && !n.ForeignKey.IsOwnership)))
{
stringBuilder.AppendLine();
Expand All @@ -169,13 +166,21 @@ protected virtual void GenerateEntityType(
var ownership = entityType.FindOwnership();
var ownerNavigation = ownership?.PrincipalToDependent.Name;

var entityTypeName = entityType.Name;
if (ownerNavigation != null
&& entityType.HasSharedClrType
&& entityTypeName == ownership.PrincipalEntityType.GetOwnedName(entityType.ClrType.ShortDisplayName(), ownerNavigation))
{
entityTypeName = entityType.ClrType.DisplayName();
}

stringBuilder
.Append(builderName)
.Append(
ownerNavigation != null
? ownership.IsUnique ? ".OwnsOne(" : ".OwnsMany("
: ".Entity(")
.Append(Code.Literal(entityType.Name));
.Append(Code.Literal(entityTypeName));

if (ownerNavigation != null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1399,8 +1399,7 @@ protected override Expression VisitExtension(Expression extensionExpression)

var targetEntityType = navigation.TargetEntityType;
if (targetEntityType == null
|| (!targetEntityType.HasDefiningNavigation()
&& !targetEntityType.IsOwned()))
|| !targetEntityType.IsOwned())
{
return null;
}
Expand Down
3 changes: 2 additions & 1 deletion src/EFCore.Proxies/Properties/ProxiesStrings.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/EFCore.Proxies/Properties/ProxiesStrings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@
</data>
<data name="EntityTypeNotFoundWeak" xml:space="preserve">
<value>Cannot create a proxy for '{typeName}' because it is mapped to multiple owned entity types. Proxy creation is not supported for owned types used more than once in the model.</value>
<comment>Obsolete</comment>
</data>
<data name="FieldProperty" xml:space="preserve">
<value>Property '{property}' on entity type '{entityType}' is mapped without a CLR property. 'UseChangeTrackingProxies' requires all entity types to be public, unsealed, have virtual properties, and have a public or protected constructor. 'UseLazyLoadingProxies' requires only the navigation properties be virtual.</value>
Expand Down
5 changes: 0 additions & 5 deletions src/EFCore.Proxies/Proxies/Internal/ProxyFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,6 @@ public virtual object Create(
throw new InvalidOperationException(ProxiesStrings.EntityTypeNotFoundShared(type.ShortDisplayName()));
}

if (context.Model.HasEntityTypeWithDefiningNavigation(type))
{
throw new InvalidOperationException(ProxiesStrings.EntityTypeNotFoundWeak(type.ShortDisplayName()));
}

throw new InvalidOperationException(CoreStrings.EntityTypeNotFound(type.ShortDisplayName()));
}

Expand Down
42 changes: 19 additions & 23 deletions src/EFCore.Relational/Extensions/RelationalEntityTypeExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,16 @@ public static string GetDefaultTableName([NotNull] this IEntityType entityType,
}

var name = entityType.ShortName();
if (entityType.HasDefiningNavigation())
if (entityType.HasSharedClrType
&& ownership != null
#pragma warning disable EF1001 // Internal EF Core API usage.
&& entityType.Name == ownership.PrincipalEntityType.GetOwnedName(name, ownership.PrincipalToDependent.Name))
#pragma warning restore EF1001 // Internal EF Core API usage.
{
var definingTypeName = entityType.DefiningEntityType.GetTableName();
name = definingTypeName != null
? $"{definingTypeName}_{entityType.DefiningNavigationName}"
: $"{entityType.DefiningNavigationName}_{name}";
var ownerTypeTable = ownership.PrincipalEntityType.GetTableName();
name = ownerTypeTable != null
? $"{ownerTypeTable}_{ownership.PrincipalToDependent.Name}"
: $"{ownership.PrincipalToDependent.Name}_{name}";
}

return truncate
Expand Down Expand Up @@ -141,31 +145,23 @@ public static string GetSchema([NotNull] this IEntityType entityType)
public static string GetDefaultSchema([NotNull] this IEntityType entityType)
{
var ownership = entityType.FindOwnership();
if (ownership != null
&& ownership.IsUnique)
if (ownership != null)
{
return ownership.PrincipalEntityType.GetSchema();
}

if (entityType.HasDefiningNavigation())
var skipNavigationSchema = entityType.GetForeignKeys().SelectMany(fk => fk.GetReferencingSkipNavigations())
.FirstOrDefault(n => !n.IsOnDependent)
?.DeclaringEntityType.GetSchema();
if (skipNavigationSchema != null
&& entityType.GetForeignKeys().SelectMany(fk => fk.GetReferencingSkipNavigations())
.Where(n => !n.IsOnDependent)
.All(n => n.DeclaringEntityType.GetSchema() == skipNavigationSchema))
{
return entityType.DefiningEntityType.GetSchema() ?? entityType.Model.GetDefaultSchema();
return skipNavigationSchema;
}
else
{
var skipReferencingTypes = entityType.GetForeignKeys().SelectMany(fk => fk.GetReferencingSkipNavigations())
.Where(n => !n.IsOnDependent && n.DeclaringEntityType != entityType)
.ToList();
var skipNavigationSchema = skipReferencingTypes.FirstOrDefault()?.DeclaringEntityType.GetSchema();
if (skipNavigationSchema != null
&& skipReferencingTypes.Skip(1)
.All(n => n.DeclaringEntityType.GetSchema() == skipNavigationSchema))
{
return skipNavigationSchema;
}

return entityType.Model.GetDefaultSchema();
}
return entityType.Model.GetDefaultSchema();
}

/// <summary>
Expand Down
3 changes: 2 additions & 1 deletion src/EFCore.Relational/Metadata/Internal/RelationalModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,8 @@ public static IModel Add(

private static void AddDefaultMappings(RelationalModel databaseModel, IConventionEntityType entityType)
{
var name = entityType.GetRootType().FullName();
var rootType = entityType.GetRootType();
var name = rootType.HasSharedClrType ? rootType.FullName() : rootType.ShortName();
if (!databaseModel.DefaultTables.TryGetValue(name, out var defaultTable))
{
defaultTable = new TableBase(name, null, databaseModel);
Expand Down
31 changes: 8 additions & 23 deletions src/EFCore.Relational/Migrations/Internal/MigrationsModelDiffer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -947,39 +947,24 @@ private static bool EntityTypePathEquals(IEntityType source, IEntityType target,
return false;
}

if (GetDefiningNavigationName(source) != GetDefiningNavigationName(target))
{
return false;
}

var nextSource = source.DefiningEntityType;
var nextTarget = target.DefiningEntityType;
var nextSource = GetLinkedPrincipal(source);
var nextTarget = GetLinkedPrincipal(target);
return (nextSource == null && nextTarget == null)
|| (nextSource != null
&& nextTarget != null
&& EntityTypePathEquals(nextSource, nextTarget, diffContext));
}

private static string GetDefiningNavigationName(IEntityType entityType)
private static IEntityType GetLinkedPrincipal(IEntityType entityType)
{
if (entityType.DefiningNavigationName != null)
var table = StoreObjectIdentifier.Create(entityType, StoreObjectType.Table);
if (table == null)
{
return entityType.DefiningNavigationName;
}

var primaryKey = entityType.BaseType == null ? entityType.FindPrimaryKey() : null;
if (primaryKey != null)
{
var definingForeignKey = entityType
.FindForeignKeys(primaryKey.Properties)
.FirstOrDefault(fk => fk.PrincipalEntityType.GetTableName() == entityType.GetTableName());
if (definingForeignKey?.DependentToPrincipal != null)
{
return definingForeignKey.DependentToPrincipal.Name;
}
return null;
}

return entityType.Name;
var linkingForeignKey = entityType.FindRowInternalForeignKeys(table.Value).FirstOrDefault();
return linkingForeignKey?.PrincipalEntityType;
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1349,8 +1349,7 @@ protected override Expression VisitExtension(Expression extensionExpression)

var targetEntityType = navigation.TargetEntityType;
if (targetEntityType == null
|| (!targetEntityType.HasDefiningNavigation()
&& !targetEntityType.IsOwned()))
|| !targetEntityType.IsOwned())
{
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,20 +47,20 @@ public virtual int Compare(ModificationCommand x, ModificationCommand y)
}

result = StringComparer.Ordinal.Compare(x.Schema, y.Schema);
if (0 != result)
if (result != 0)
{
return result;
}

result = StringComparer.Ordinal.Compare(x.TableName, y.TableName);
if (0 != result)
if (result != 0)
{
return result;
}

var xState = x.EntityState;
result = (int)xState - (int)y.EntityState;
if (0 != result)
if (result != 0)
{
return result;
}
Expand All @@ -77,13 +77,7 @@ public virtual int Compare(ModificationCommand x, ModificationCommand y)
if (xEntityType != yEntityType)
{
result = StringComparer.Ordinal.Compare(xEntityType.Name, yEntityType.Name);
if (0 != result)
{
return result;
}

result = StringComparer.Ordinal.Compare(xEntityType.DefiningNavigationName, yEntityType.DefiningNavigationName);
if (0 != result)
if (result != 0)
{
return result;
}
Expand All @@ -95,7 +89,7 @@ public virtual int Compare(ModificationCommand x, ModificationCommand y)
var xKeyProperty = xKey.Properties[i];

result = xKeyProperty.GetCurrentValueComparer().Compare(xEntry, yEntry);
if (0 != result)
if (result != 0)
{
return result;
}
Expand Down
Loading

0 comments on commit fd9155f

Please sign in to comment.