mirror of
https://github.com/fergalmoran/EFCore.NamingConventions.git
synced 2025-12-22 09:38:21 +00:00
Avoiding rewriting PK name for owned entity in a TPT hierarchy (#63)
Fixes #62
This commit is contained in:
@@ -157,6 +157,75 @@ namespace EFCore.NamingConventions.Test
|
|||||||
Assert.Equal("PK_parent", childKey.GetName());
|
Assert.Equal("PK_parent", childKey.GetName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TPH_with_owned()
|
||||||
|
{
|
||||||
|
var model = BuildModel(b =>
|
||||||
|
{
|
||||||
|
b.Entity<Parent>();
|
||||||
|
b.Entity<ChildWithOwned>().OwnsOne(c => c.Owned);
|
||||||
|
});
|
||||||
|
|
||||||
|
var parentEntityType = model.FindEntityType(typeof(Parent));
|
||||||
|
var childEntityType = model.FindEntityType(typeof(ChildWithOwned));
|
||||||
|
var ownedEntityType = model.FindEntityType(typeof(Owned));
|
||||||
|
|
||||||
|
Assert.Equal("parent", parentEntityType.GetTableName());
|
||||||
|
Assert.Equal("id", parentEntityType.FindProperty(nameof(Parent.Id))
|
||||||
|
.GetColumnName(StoreObjectIdentifier.Create(parentEntityType, StoreObjectType.Table)!.Value));
|
||||||
|
Assert.Equal("parent_property", parentEntityType.FindProperty(nameof(Parent.ParentProperty))
|
||||||
|
.GetColumnName(StoreObjectIdentifier.Create(childEntityType, StoreObjectType.Table)!.Value));
|
||||||
|
|
||||||
|
Assert.Equal("parent", childEntityType.GetTableName());
|
||||||
|
Assert.Equal("child_property", childEntityType.FindProperty(nameof(Child.ChildProperty))
|
||||||
|
.GetColumnName(StoreObjectIdentifier.Create(childEntityType, StoreObjectType.Table)!.Value));
|
||||||
|
|
||||||
|
Assert.Same(parentEntityType.FindPrimaryKey(), childEntityType.FindPrimaryKey());
|
||||||
|
|
||||||
|
Assert.Equal("parent", ownedEntityType.GetTableName());
|
||||||
|
Assert.Equal("owned_owned_property", ownedEntityType.FindProperty(nameof(Owned.OwnedProperty))
|
||||||
|
.GetColumnName(StoreObjectIdentifier.Create(ownedEntityType, StoreObjectType.Table)!.Value));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TPT_with_owned()
|
||||||
|
{
|
||||||
|
var model = BuildModel(b =>
|
||||||
|
{
|
||||||
|
b.Entity<Parent>().ToTable("parent");
|
||||||
|
b.Entity<ChildWithOwned>(
|
||||||
|
e =>
|
||||||
|
{
|
||||||
|
e.ToTable("child");
|
||||||
|
e.OwnsOne(c => c.Owned);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
var parentEntityType = model.FindEntityType(typeof(Parent));
|
||||||
|
var childEntityType = model.FindEntityType(typeof(ChildWithOwned));
|
||||||
|
var ownedEntityType = model.FindEntityType(typeof(Owned));
|
||||||
|
|
||||||
|
Assert.Equal("parent", parentEntityType.GetTableName());
|
||||||
|
Assert.Equal("id", parentEntityType.FindProperty(nameof(Parent.Id))
|
||||||
|
.GetColumnName(StoreObjectIdentifier.Create(parentEntityType, StoreObjectType.Table)!.Value));
|
||||||
|
Assert.Equal("parent_property", parentEntityType.FindProperty(nameof(Parent.ParentProperty))
|
||||||
|
.GetColumnName(StoreObjectIdentifier.Create(parentEntityType, StoreObjectType.Table)!.Value));
|
||||||
|
|
||||||
|
Assert.Equal("child", childEntityType.GetTableName());
|
||||||
|
Assert.Equal("child_property", childEntityType.FindProperty(nameof(ChildWithOwned.ChildProperty))
|
||||||
|
.GetColumnName(StoreObjectIdentifier.Create(childEntityType, StoreObjectType.Table)!.Value));
|
||||||
|
|
||||||
|
var parentKey = parentEntityType.FindPrimaryKey();
|
||||||
|
var childKey = childEntityType.FindPrimaryKey();
|
||||||
|
|
||||||
|
Assert.Equal("PK_parent", parentKey.GetName());
|
||||||
|
Assert.Equal("PK_parent", childKey.GetName());
|
||||||
|
|
||||||
|
Assert.Equal("child", ownedEntityType.GetTableName());
|
||||||
|
Assert.Equal("owned_owned_property", ownedEntityType.FindProperty(nameof(Owned.OwnedProperty))
|
||||||
|
.GetColumnName(StoreObjectIdentifier.Create(ownedEntityType, StoreObjectType.Table)!.Value));
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Table_splitting()
|
public void Table_splitting()
|
||||||
{
|
{
|
||||||
@@ -281,6 +350,12 @@ namespace EFCore.NamingConventions.Test
|
|||||||
public int ChildProperty { get; set; }
|
public int ChildProperty { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class ChildWithOwned : Parent
|
||||||
|
{
|
||||||
|
public int ChildProperty { get; set; }
|
||||||
|
public Owned Owned { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
public class Split1
|
public class Split1
|
||||||
{
|
{
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
using Microsoft.EntityFrameworkCore.Metadata;
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||||
using Microsoft.EntityFrameworkCore.Metadata.Conventions;
|
using Microsoft.EntityFrameworkCore.Metadata.Conventions;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata.Internal;
|
||||||
|
|
||||||
namespace EFCore.NamingConventions.Internal
|
namespace EFCore.NamingConventions.Internal
|
||||||
{
|
{
|
||||||
@@ -94,20 +95,36 @@ namespace EFCore.NamingConventions.Internal
|
|||||||
public void ProcessEntityTypeAnnotationChanged(IConventionEntityTypeBuilder entityTypeBuilder, string name,
|
public void ProcessEntityTypeAnnotationChanged(IConventionEntityTypeBuilder entityTypeBuilder, string name,
|
||||||
IConventionAnnotation annotation, IConventionAnnotation oldAnnotation, IConventionContext<IConventionAnnotation> context)
|
IConventionAnnotation annotation, IConventionAnnotation oldAnnotation, IConventionContext<IConventionAnnotation> context)
|
||||||
{
|
{
|
||||||
if (name != RelationalAnnotationNames.TableName)
|
var entityType = entityTypeBuilder.Metadata;
|
||||||
|
|
||||||
|
if (name != RelationalAnnotationNames.TableName
|
||||||
|
|| StoreObjectIdentifier.Create(entityType, StoreObjectType.Table) is not StoreObjectIdentifier tableIdentifier)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var entityType = entityTypeBuilder.Metadata;
|
|
||||||
|
|
||||||
// The table's name is changing - rewrite keys, index names
|
// The table's name is changing - rewrite keys, index names
|
||||||
|
|
||||||
if (entityType.FindPrimaryKey() is IConventionKey primaryKey)
|
if (entityType.FindPrimaryKey() is IConventionKey primaryKey)
|
||||||
{
|
{
|
||||||
if (entityType.BaseType is not null
|
// We need to rewrite the PK name.
|
||||||
&& entityType.GetTableName() != entityType.BaseType.GetTableName())
|
// However, this isn't yet supported with TPT, see https://github.com/dotnet/efcore/issues/23444.
|
||||||
|
// So we need to check if the entity is within a TPT hierarchy, or is an owned entity within a TPT hierarchy.
|
||||||
|
var tempEntityType = (IEntityType)entityType;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
var foreignKey = tempEntityType.FindRowInternalForeignKeys(tableIdentifier).FirstOrDefault();
|
||||||
|
if (foreignKey is null)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
tempEntityType = foreignKey.PrincipalEntityType;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tempEntityType.BaseType is not null
|
||||||
|
&& tempEntityType.GetTableName() != tempEntityType.BaseType.GetTableName())
|
||||||
{
|
{
|
||||||
// It's not yet possible to set the PK name with TPT, see https://github.com/dotnet/efcore/issues/23444.
|
|
||||||
primaryKey.Builder.HasNoAnnotation(RelationalAnnotationNames.Name);
|
primaryKey.Builder.HasNoAnnotation(RelationalAnnotationNames.Name);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
Reference in New Issue
Block a user