mirror of
https://github.com/fergalmoran/EFCore.NamingConventions.git
synced 2025-12-22 09:38:21 +00:00
Fix owned entity support (#58)
* Also avoid rewriting primary key name with TPT * Also redo tests again to be properly end-to-end Fixes #50
This commit is contained in:
@@ -11,7 +11,6 @@
|
|||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Specification.Tests" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Specification.Tests" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Specification.Tests" />
|
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration" />
|
<PackageReference Include="Microsoft.Extensions.Configuration" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Json" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" />
|
||||||
|
|||||||
@@ -1,103 +0,0 @@
|
|||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using Microsoft.Data.Sqlite;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.EntityFrameworkCore.Metadata;
|
|
||||||
using Xunit;
|
|
||||||
|
|
||||||
namespace EFCore.NamingConventions.Test
|
|
||||||
{
|
|
||||||
public class EndToEndTest : IClassFixture<EndToEndTest.EndToEndTestFixture>
|
|
||||||
{
|
|
||||||
public EndToEndTest(EndToEndTestFixture fixture)
|
|
||||||
=> Fixture = fixture;
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Table_splitting()
|
|
||||||
{
|
|
||||||
using var context = CreateContext();
|
|
||||||
|
|
||||||
var split1EntityType = context.Model.FindEntityType(typeof(Split1));
|
|
||||||
var split2EntityType = context.Model.FindEntityType(typeof(Split2));
|
|
||||||
|
|
||||||
var table = StoreObjectIdentifier.Create(split1EntityType, StoreObjectType.Table)!.Value;
|
|
||||||
Assert.Equal(table, StoreObjectIdentifier.Create(split2EntityType, StoreObjectType.Table));
|
|
||||||
|
|
||||||
Assert.Equal("common", split1EntityType.FindProperty("Common").GetColumnName(table));
|
|
||||||
Assert.Equal("split2_common", split2EntityType.FindProperty("Common").GetColumnName(table));
|
|
||||||
|
|
||||||
var split1 = context.Set<Split1>().Include(s1 => s1.Split2).Single();
|
|
||||||
Assert.Equal(100, split1.Common);
|
|
||||||
Assert.Equal(101, split1.Split2.Common);
|
|
||||||
}
|
|
||||||
|
|
||||||
TestContext CreateContext() => Fixture.CreateContext();
|
|
||||||
|
|
||||||
readonly EndToEndTestFixture Fixture;
|
|
||||||
|
|
||||||
public class TestContext : DbContext
|
|
||||||
{
|
|
||||||
public TestContext(SqliteConnection connection)
|
|
||||||
: base(new DbContextOptionsBuilder<TestContext>()
|
|
||||||
.UseSqlite(connection)
|
|
||||||
.UseSnakeCaseNamingConvention()
|
|
||||||
.Options)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
|
||||||
{
|
|
||||||
modelBuilder.Entity<Split1>(e =>
|
|
||||||
{
|
|
||||||
e.ToTable("split");
|
|
||||||
e.HasOne(s1 => s1.Split2).WithOne(s2 => s2.Split1).HasForeignKey<Split2>(s2 => s2.Id);
|
|
||||||
e.HasData(new Split1 { Id = 1, OneProp = 1, Common = 100 });
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity<Split2>(e =>
|
|
||||||
{
|
|
||||||
e.ToTable("split");
|
|
||||||
e.HasData(new Split2 { Id = 1, TwoProp = 2, Common = 101 });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Split1
|
|
||||||
{
|
|
||||||
public int Id { get; set; }
|
|
||||||
public int OneProp { get; set; }
|
|
||||||
public int Common { get; set; }
|
|
||||||
|
|
||||||
public Split2 Split2 { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Split2
|
|
||||||
{
|
|
||||||
public int Id { get; set; }
|
|
||||||
public int TwoProp { get; set; }
|
|
||||||
public int Common { get; set; }
|
|
||||||
|
|
||||||
public Split1 Split1 { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class EndToEndTestFixture : IDisposable
|
|
||||||
{
|
|
||||||
private readonly SqliteConnection _connection;
|
|
||||||
|
|
||||||
public TestContext CreateContext() => new(_connection);
|
|
||||||
|
|
||||||
public EndToEndTestFixture()
|
|
||||||
{
|
|
||||||
_connection = new SqliteConnection("Filename=:memory:");
|
|
||||||
_connection.Open();
|
|
||||||
using var context = new TestContext(_connection);
|
|
||||||
context.Database.EnsureCreated();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose() => _connection.Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,283 +1,131 @@
|
|||||||
using System;
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using EFCore.NamingConventions.Internal;
|
using EFCore.NamingConventions.Internal;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Metadata;
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
|
||||||
using Microsoft.EntityFrameworkCore.Metadata.Conventions;
|
|
||||||
using Microsoft.EntityFrameworkCore.TestUtilities;
|
using Microsoft.EntityFrameworkCore.TestUtilities;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
// ReSharper disable UnusedMember.Global
|
|
||||||
|
|
||||||
namespace EFCore.NamingConventions.Test
|
namespace EFCore.NamingConventions.Test
|
||||||
{
|
{
|
||||||
public class NameRewritingConventionTest
|
public class NameRewritingConventionTest
|
||||||
{
|
{
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Table_name()
|
public void Table()
|
||||||
{
|
{
|
||||||
var entityType = BuildEntityType("SimpleBlog", _ => {});
|
var entityType = BuildEntityType(b => b.Entity<SampleEntity>());
|
||||||
Assert.Equal("simple_blog", entityType.GetTableName());
|
Assert.Equal("sample_entity", entityType.GetTableName());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Column_name()
|
public void Column()
|
||||||
{
|
{
|
||||||
var entityType = BuildEntityType("SimpleBlog", e => e.Property<int>("SimpleBlogId"));
|
var entityType = BuildEntityType(b => b.Entity<SampleEntity>());
|
||||||
|
Assert.Equal("sample_entity_id", entityType.FindProperty(nameof(SampleEntity.SampleEntityId))
|
||||||
Assert.Equal("simple_blog_id", entityType.FindProperty("SimpleBlogId")
|
|
||||||
.GetColumnName(StoreObjectIdentifier.Create(entityType, StoreObjectType.Table)!.Value));
|
.GetColumnName(StoreObjectIdentifier.Create(entityType, StoreObjectType.Table)!.Value));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Column_name_on_view()
|
public void Column_with_turkish_culture()
|
||||||
{
|
{
|
||||||
var entityType = BuildEntityType("SimpleBlog", e =>
|
var entityType = BuildEntityType(
|
||||||
{
|
b => b.Entity<SampleEntity>(),
|
||||||
e.ToTable("SimpleBlogTable");
|
CultureInfo.CreateSpecificCulture("tr-TR"));
|
||||||
e.ToView("SimpleBlogView");
|
Assert.Equal("sample_entity_ıd", entityType.FindProperty(nameof(SampleEntity.SampleEntityId))
|
||||||
e.ToFunction("SimpleBlogFunction");
|
.GetColumnName(StoreObjectIdentifier.Create(entityType, StoreObjectType.Table)!.Value));
|
||||||
e.Property<int>("SimpleBlogId");
|
}
|
||||||
});
|
|
||||||
|
[Fact]
|
||||||
|
public void Column_with_invariant_culture()
|
||||||
|
{
|
||||||
|
var entityType = BuildEntityType(
|
||||||
|
b => b.Entity<SampleEntity>(),
|
||||||
|
CultureInfo.InvariantCulture);
|
||||||
|
Assert.Equal("sample_entity_id", entityType.FindProperty(nameof(SampleEntity.SampleEntityId))
|
||||||
|
.GetColumnName(StoreObjectIdentifier.Create(entityType, StoreObjectType.Table)!.Value));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Column_on_view()
|
||||||
|
{
|
||||||
|
var entityType = BuildEntityType(b => b.Entity<SampleEntity>(
|
||||||
|
e =>
|
||||||
|
{
|
||||||
|
e.ToTable("SimpleBlogTable");
|
||||||
|
e.ToView("SimpleBlogView");
|
||||||
|
e.ToFunction("SimpleBlogFunction");
|
||||||
|
}));
|
||||||
|
|
||||||
foreach (var type in new[] { StoreObjectType.Table, StoreObjectType.View, StoreObjectType.Function })
|
foreach (var type in new[] { StoreObjectType.Table, StoreObjectType.View, StoreObjectType.Function })
|
||||||
{
|
{
|
||||||
Assert.Equal("simple_blog_id", entityType.FindProperty("SimpleBlogId")
|
Assert.Equal("sample_entity_id", entityType.FindProperty(nameof(SampleEntity.SampleEntityId))
|
||||||
.GetColumnName(StoreObjectIdentifier.Create(entityType, type)!.Value));
|
.GetColumnName(StoreObjectIdentifier.Create(entityType, type)!.Value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Column_name_turkish_culture()
|
public void Primary_key()
|
||||||
|
{
|
||||||
|
var entityType = BuildEntityType(b => b.Entity<SampleEntity>());
|
||||||
|
Assert.Equal("pk_sample_entity", entityType.GetKeys().Single(k => k.IsPrimaryKey()).GetName());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Alternative_key()
|
||||||
{
|
{
|
||||||
var entityType = BuildEntityType(
|
var entityType = BuildEntityType(
|
||||||
"SimpleBlog",
|
b => b.Entity<SampleEntity>(
|
||||||
e => e.Property<int>("SimpleBlogId"),
|
e =>
|
||||||
CultureInfo.CreateSpecificCulture("tr-TR"));
|
{
|
||||||
|
e.Property<int>("SomeAlternateKey");
|
||||||
Assert.Equal("simple_blog_ıd", entityType.FindProperty("SimpleBlogId")
|
e.HasAlternateKey("SomeAlternateKey");
|
||||||
.GetColumnName(StoreObjectIdentifier.Create(entityType, StoreObjectType.Table)!.Value));
|
}));
|
||||||
|
Assert.Equal("ak_sample_entity_some_alternate_key", entityType.GetKeys().Single(k => !k.IsPrimaryKey()).GetName());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Column_name_invariant_culture()
|
public void Foreign_key()
|
||||||
{
|
{
|
||||||
var entityType = BuildEntityType(
|
var model = BuildModel(b => b.Entity<Blog>());
|
||||||
"SimpleBlog",
|
var entityType = model.FindEntityType(typeof(Post));
|
||||||
e => e.Property<int>("SimpleBlogId"),
|
|
||||||
CultureInfo.InvariantCulture);
|
|
||||||
|
|
||||||
Assert.Equal("simple_blog_id", entityType.FindProperty("SimpleBlogId")
|
|
||||||
.GetColumnName(StoreObjectIdentifier.Create(entityType, StoreObjectType.Table)!.Value));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Primary_key_name()
|
|
||||||
{
|
|
||||||
var entityType = BuildEntityType("SimpleBlog", e =>
|
|
||||||
{
|
|
||||||
e.Property<int>("SimpleBlogId");
|
|
||||||
e.HasKey("SimpleBlogId");
|
|
||||||
});
|
|
||||||
|
|
||||||
Assert.Equal("pk_simple_blog", entityType.GetKeys().Single(k => k.IsPrimaryKey()).GetName());
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Alternative_key_name()
|
|
||||||
{
|
|
||||||
var entityType = BuildEntityType("SimpleBlog", e =>
|
|
||||||
{
|
|
||||||
e.Property<int>("SimpleBlogId");
|
|
||||||
e.Property<int>("SomeAlternativeKey");
|
|
||||||
e.HasKey("SimpleBlogId");
|
|
||||||
e.HasAlternateKey("SomeAlternativeKey");
|
|
||||||
});
|
|
||||||
|
|
||||||
Assert.Equal("ak_simple_blog_some_alternative_key", entityType.GetKeys().Single(k => !k.IsPrimaryKey()).GetName());
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Foreign_key_name()
|
|
||||||
{
|
|
||||||
var model = BuildModel(b =>
|
|
||||||
{
|
|
||||||
b.Entity("Blog", e =>
|
|
||||||
{
|
|
||||||
e.Property<int>("BlogId");
|
|
||||||
e.HasKey("BlogId");
|
|
||||||
e.HasMany("Post").WithOne("Blog");
|
|
||||||
});
|
|
||||||
b.Entity("Post", e =>
|
|
||||||
{
|
|
||||||
e.Property<int>("PostId");
|
|
||||||
e.Property<int>("BlogId");
|
|
||||||
e.HasKey("PostId");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
var entityType = model.FindEntityType("Post");
|
|
||||||
|
|
||||||
Assert.Equal("fk_post_blog_blog_id", entityType.GetForeignKeys().Single().GetConstraintName());
|
Assert.Equal("fk_post_blog_blog_id", entityType.GetForeignKeys().Single().GetConstraintName());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Index_name()
|
public void Index()
|
||||||
{
|
{
|
||||||
var entityType = BuildEntityType("SimpleBlog", e =>
|
var entityType = BuildEntityType(b => b.Entity<SampleEntity>().HasIndex(s => s.SomeProperty));
|
||||||
{
|
Assert.Equal("ix_sample_entity_some_property", entityType.GetIndexes().Single().GetDatabaseName());
|
||||||
e.Property<int>("IndexedProperty");
|
|
||||||
e.HasIndex("IndexedProperty");
|
|
||||||
});
|
|
||||||
|
|
||||||
Assert.Equal("ix_simple_blog_indexed_property", entityType.GetIndexes().Single().GetDatabaseName());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Table_splitting()
|
|
||||||
{
|
|
||||||
var model = BuildModel(b =>
|
|
||||||
{
|
|
||||||
b.Entity("One", e =>
|
|
||||||
{
|
|
||||||
e.ToTable("table");
|
|
||||||
e.Property<int>("Id");
|
|
||||||
e.Property<int>("OneProp");
|
|
||||||
e.Property<int>("Common");
|
|
||||||
|
|
||||||
e.HasOne("Two").WithOne().HasForeignKey("Two", "Id");
|
|
||||||
});
|
|
||||||
|
|
||||||
b.Entity("Two", e =>
|
|
||||||
{
|
|
||||||
e.ToTable("table");
|
|
||||||
e.Property<int>("Id");
|
|
||||||
e.Property<int>("TwoProp");
|
|
||||||
e.Property<int>("Common");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
var oneEntityType = model.FindEntityType("One");
|
|
||||||
var twoEntityType = model.FindEntityType("Two");
|
|
||||||
|
|
||||||
var table = StoreObjectIdentifier.Create(oneEntityType, StoreObjectType.Table)!.Value;
|
|
||||||
Assert.Equal(table, StoreObjectIdentifier.Create(twoEntityType, StoreObjectType.Table));
|
|
||||||
|
|
||||||
Assert.Equal("table", oneEntityType.GetTableName());
|
|
||||||
Assert.Equal("one_prop", oneEntityType.FindProperty("OneProp").GetColumnName(table));
|
|
||||||
|
|
||||||
Assert.Equal("table", twoEntityType.GetTableName());
|
|
||||||
Assert.Equal("two_prop", twoEntityType.FindProperty("TwoProp").GetColumnName(table));
|
|
||||||
|
|
||||||
var foreignKey = twoEntityType.GetForeignKeys().Single();
|
|
||||||
Assert.Same(oneEntityType.FindPrimaryKey(), foreignKey.PrincipalKey);
|
|
||||||
Assert.Same(twoEntityType.FindPrimaryKey().Properties.Single(), foreignKey.Properties.Single());
|
|
||||||
Assert.Equal(oneEntityType.FindPrimaryKey().GetName(), twoEntityType.FindPrimaryKey().GetName());
|
|
||||||
|
|
||||||
Assert.Equal(
|
|
||||||
foreignKey.PrincipalKey.Properties.Single().GetColumnName(table),
|
|
||||||
foreignKey.Properties.Single().GetColumnName(table));
|
|
||||||
|
|
||||||
Assert.Empty(oneEntityType.GetForeignKeys());
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Owned entities
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Owned_entity_with_table_splitting()
|
|
||||||
{
|
|
||||||
var model = BuildModel(b =>
|
|
||||||
{
|
|
||||||
b.Entity("SimpleBlog", e =>
|
|
||||||
{
|
|
||||||
e.OwnsOne("OwnedEntity", "Nav", o => o.Property<int>("OwnedProperty"));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
var entityType = model.FindEntityType("OwnedEntity");
|
|
||||||
Assert.Equal("pk_simple_blog", entityType.FindPrimaryKey().GetName());
|
|
||||||
Assert.Equal("simple_blog", entityType.GetTableName());
|
|
||||||
Assert.Equal("owned_property", entityType.FindProperty("OwnedProperty")
|
|
||||||
.GetColumnName(StoreObjectIdentifier.Create(entityType, StoreObjectType.Table)!.Value));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Owned_entity_without_table_splitting()
|
|
||||||
{
|
|
||||||
var model = BuildModel(b =>
|
|
||||||
{
|
|
||||||
b.Entity("SimpleBlog", e =>
|
|
||||||
{
|
|
||||||
e.Property<int>("SimpleBlogId");
|
|
||||||
e.HasKey("SimpleBlogId");
|
|
||||||
e.OwnsOne("OwnedEntity", "Nav", o =>
|
|
||||||
{
|
|
||||||
o.ToTable("another_table");
|
|
||||||
o.Property<int>("OwnedProperty");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
var entityType = model.FindEntityType("OwnedEntity");
|
|
||||||
|
|
||||||
Assert.Equal("pk_another_table", entityType.FindPrimaryKey().GetName());
|
|
||||||
Assert.Equal("another_table", entityType.GetTableName());
|
|
||||||
Assert.Equal("owned_property", entityType.FindProperty("OwnedProperty")
|
|
||||||
.GetColumnName(StoreObjectIdentifier.Create(entityType, StoreObjectType.Table)!.Value));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Owned_entity_with_view_without_table_splitting()
|
|
||||||
{
|
|
||||||
var model = BuildModel(b =>
|
|
||||||
{
|
|
||||||
b.Entity("OwnedEntity", e =>
|
|
||||||
{
|
|
||||||
e.ToTable("OwnedEntityTable");
|
|
||||||
e.ToView("OwnedEntityView");
|
|
||||||
e.Property<int>("OwnedProperty");
|
|
||||||
});
|
|
||||||
b.Entity("SimpleBlog", e => e.OwnsOne("OwnedEntity", "Nav"));
|
|
||||||
});
|
|
||||||
var entityType = model.FindEntityType("OwnedEntity");
|
|
||||||
|
|
||||||
Assert.Equal("OwnedEntityTable", entityType.GetTableName());
|
|
||||||
Assert.Equal("OwnedEntityView", entityType.GetViewName());
|
|
||||||
Assert.Equal("owned_property", entityType.FindProperty("OwnedProperty")
|
|
||||||
.GetColumnName(StoreObjectIdentifier.Create(entityType, StoreObjectType.Table)!.Value));
|
|
||||||
Assert.Equal("owned_property", entityType.FindProperty("OwnedProperty")
|
|
||||||
.GetColumnName(StoreObjectIdentifier.Create(entityType, StoreObjectType.View)!.Value));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Owned entities
|
|
||||||
|
|
||||||
#region Inheritance
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void TPH()
|
public void TPH()
|
||||||
{
|
{
|
||||||
var model = BuildModel(b =>
|
var model = BuildModel(b =>
|
||||||
{
|
{
|
||||||
b.Entity("SimpleBlog", e =>
|
b.Entity<Parent>();
|
||||||
{
|
b.Entity<Child>();
|
||||||
e.Property<int>("SimpleBlogId");
|
|
||||||
e.HasKey("SimpleBlogId");
|
|
||||||
});
|
|
||||||
b.Entity("FancyBlog", e =>
|
|
||||||
{
|
|
||||||
e.HasBaseType("SimpleBlog");
|
|
||||||
e.Property<int>("FancyProperty");
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var simpleBlogEntityType = model.FindEntityType("SimpleBlog");
|
var parentEntityType = model.FindEntityType(typeof(Parent));
|
||||||
Assert.Equal("simple_blog", simpleBlogEntityType.GetTableName());
|
var childEntityType = model.FindEntityType(typeof(Child));
|
||||||
Assert.Equal("simple_blog_id", simpleBlogEntityType.FindProperty("SimpleBlogId")
|
|
||||||
.GetColumnName(StoreObjectIdentifier.Create(simpleBlogEntityType, StoreObjectType.Table)!.Value));
|
|
||||||
|
|
||||||
var fancyBlogEntityType = model.FindEntityType("FancyBlog");
|
Assert.Equal("parent", parentEntityType.GetTableName());
|
||||||
Assert.Equal("simple_blog", fancyBlogEntityType.GetTableName());
|
Assert.Equal("id", parentEntityType.FindProperty(nameof(Parent.Id))
|
||||||
Assert.Equal("fancy_property", fancyBlogEntityType.FindProperty("FancyProperty")
|
.GetColumnName(StoreObjectIdentifier.Create(parentEntityType, StoreObjectType.Table)!.Value));
|
||||||
.GetColumnName(StoreObjectIdentifier.Create(fancyBlogEntityType, 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());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -285,51 +133,182 @@ namespace EFCore.NamingConventions.Test
|
|||||||
{
|
{
|
||||||
var model = BuildModel(b =>
|
var model = BuildModel(b =>
|
||||||
{
|
{
|
||||||
b.Entity("SimpleBlog", e =>
|
b.Entity<Parent>().ToTable("parent");
|
||||||
{
|
b.Entity<Child>().ToTable("child");
|
||||||
e.Property<int>("SimpleBlogId");
|
|
||||||
e.HasKey("SimpleBlogId");
|
|
||||||
});
|
|
||||||
b.Entity("FancyBlog", e =>
|
|
||||||
{
|
|
||||||
e.HasBaseType("SimpleBlog");
|
|
||||||
e.ToTable("fancy_blog");
|
|
||||||
e.Property<int>("FancyProperty");
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var simpleBlogEntityType = model.FindEntityType("SimpleBlog");
|
var parentEntityType = model.FindEntityType(typeof(Parent));
|
||||||
Assert.Equal("simple_blog", simpleBlogEntityType.GetTableName());
|
var childEntityType = model.FindEntityType(typeof(Child));
|
||||||
Assert.Equal("simple_blog_id", simpleBlogEntityType.FindProperty("SimpleBlogId")
|
|
||||||
.GetColumnName(StoreObjectIdentifier.Create(simpleBlogEntityType, StoreObjectType.Table)!.Value));
|
|
||||||
|
|
||||||
var fancyBlogEntityType = model.FindEntityType("FancyBlog");
|
Assert.Equal("parent", parentEntityType.GetTableName());
|
||||||
Assert.Equal("fancy_blog", fancyBlogEntityType.GetTableName());
|
Assert.Equal("id", parentEntityType.FindProperty(nameof(Parent.Id))
|
||||||
Assert.Equal("fancy_property", fancyBlogEntityType.FindProperty("FancyProperty")
|
.GetColumnName(StoreObjectIdentifier.Create(parentEntityType, StoreObjectType.Table)!.Value));
|
||||||
.GetColumnName(StoreObjectIdentifier.Create(fancyBlogEntityType, 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(Child.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());
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion Inheritance
|
[Fact]
|
||||||
|
public void Table_splitting()
|
||||||
#region Support
|
|
||||||
|
|
||||||
private IModel BuildModel(Action<ModelBuilder> buildAction, CultureInfo cultureInfo = null)
|
|
||||||
{
|
{
|
||||||
var conventionSet = InMemoryTestHelpers.Instance.CreateConventionSetBuilder().CreateConventionSet();
|
var model = BuildModel(b =>
|
||||||
ConventionSet.Remove(conventionSet.ModelFinalizedConventions, typeof(ValidatingConvention));
|
{
|
||||||
|
b.Entity<Split1>(
|
||||||
|
e =>
|
||||||
|
{
|
||||||
|
e.ToTable("split_table");
|
||||||
|
e.HasOne(s1 => s1.S2).WithOne(s2 => s2.S1).HasForeignKey<Split2>(s2 => s2.Id);
|
||||||
|
});
|
||||||
|
|
||||||
|
b.Entity<Split2>(e => e.ToTable("split_table"));
|
||||||
|
});
|
||||||
|
|
||||||
|
var split1EntityType = model.FindEntityType(typeof(Split1));
|
||||||
|
var split2EntityType = model.FindEntityType(typeof(Split2));
|
||||||
|
|
||||||
|
var table = StoreObjectIdentifier.Create(split1EntityType, StoreObjectType.Table)!.Value;
|
||||||
|
Assert.Equal(table, StoreObjectIdentifier.Create(split2EntityType, StoreObjectType.Table));
|
||||||
|
|
||||||
|
Assert.Equal("split_table", split1EntityType.GetTableName());
|
||||||
|
Assert.Equal("one_prop", split1EntityType.FindProperty(nameof(Split1.OneProp)).GetColumnName(table));
|
||||||
|
|
||||||
|
Assert.Equal("split_table", split2EntityType.GetTableName());
|
||||||
|
Assert.Equal("two_prop", split2EntityType.FindProperty(nameof(Split2.TwoProp)).GetColumnName(table));
|
||||||
|
|
||||||
|
Assert.Equal("common", split1EntityType.FindProperty(nameof(Split1.Common)).GetColumnName(table));
|
||||||
|
Assert.Equal("split2_common", split2EntityType.FindProperty(nameof(Split2.Common)).GetColumnName(table));
|
||||||
|
|
||||||
|
var foreignKey = split2EntityType.GetForeignKeys().Single();
|
||||||
|
Assert.Same(split1EntityType.FindPrimaryKey(), foreignKey.PrincipalKey);
|
||||||
|
Assert.Same(split2EntityType.FindPrimaryKey().Properties.Single(), foreignKey.Properties.Single());
|
||||||
|
Assert.Equal(split1EntityType.FindPrimaryKey().GetName(), split2EntityType.FindPrimaryKey().GetName());
|
||||||
|
Assert.Equal(
|
||||||
|
foreignKey.PrincipalKey.Properties.Single().GetColumnName(table),
|
||||||
|
foreignKey.Properties.Single().GetColumnName(table));
|
||||||
|
Assert.Empty(split1EntityType.GetForeignKeys());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Owned_entity_with_table_splitting()
|
||||||
|
{
|
||||||
|
var model = BuildModel(b => b.Entity<Owner>().OwnsOne(o => o.Owned));
|
||||||
|
|
||||||
|
var ownerEntityType = model.FindEntityType(typeof(Owner));
|
||||||
|
var ownedEntityType = model.FindEntityType(typeof(Owned));
|
||||||
|
|
||||||
|
Assert.Equal("owner", ownerEntityType.GetTableName());
|
||||||
|
Assert.Equal("owner", ownedEntityType.GetTableName());
|
||||||
|
var table = StoreObjectIdentifier.Create(ownerEntityType, StoreObjectType.Table)!.Value;
|
||||||
|
Assert.Equal(table, StoreObjectIdentifier.Create(ownedEntityType, StoreObjectType.Table)!.Value);
|
||||||
|
|
||||||
|
Assert.Equal("owned_owned_property", ownedEntityType.FindProperty(nameof(Owned.OwnedProperty)).GetColumnName(table));
|
||||||
|
|
||||||
|
var (ownerKey, ownedKey) = (ownerEntityType.FindPrimaryKey(), ownedEntityType.FindPrimaryKey());
|
||||||
|
Assert.Equal("pk_owner", ownerKey.GetName());
|
||||||
|
Assert.Equal("pk_owner", ownedKey.GetName());
|
||||||
|
Assert.Equal("id", ownerKey.Properties.Single().GetColumnName(table));
|
||||||
|
Assert.Equal("id", ownedKey.Properties.Single().GetColumnName(table));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Owned_entity_without_table_splitting()
|
||||||
|
{
|
||||||
|
var model = BuildModel(b =>
|
||||||
|
b.Entity<Owner>().OwnsOne(o => o.Owned).ToTable("another_table"));
|
||||||
|
|
||||||
|
var ownedEntityType = model.FindEntityType(typeof(Owned));
|
||||||
|
|
||||||
|
Assert.Equal("pk_another_table", ownedEntityType.FindPrimaryKey().GetName());
|
||||||
|
Assert.Equal("another_table", ownedEntityType.GetTableName());
|
||||||
|
Assert.Equal("owned_property", ownedEntityType.FindProperty("OwnedProperty")
|
||||||
|
.GetColumnName(StoreObjectIdentifier.Create(ownedEntityType, StoreObjectType.Table)!.Value));
|
||||||
|
}
|
||||||
|
|
||||||
|
private IEntityType BuildEntityType(Action<ModelBuilder> builderAction, CultureInfo culture = null)
|
||||||
|
=> BuildModel(builderAction, culture).GetEntityTypes().Single();
|
||||||
|
|
||||||
|
private IModel BuildModel(Action<ModelBuilder> builderAction, CultureInfo culture = null)
|
||||||
|
{
|
||||||
|
var conventionSet = SqliteTestHelpers.Instance.CreateConventionSetBuilder().CreateConventionSet();
|
||||||
|
|
||||||
var optionsBuilder = new DbContextOptionsBuilder();
|
var optionsBuilder = new DbContextOptionsBuilder();
|
||||||
optionsBuilder.UseSnakeCaseNamingConvention(cultureInfo);
|
SqliteTestHelpers.Instance.UseProviderOptions(optionsBuilder);
|
||||||
new NamingConventionSetPlugin(optionsBuilder.Options).ModifyConventions(conventionSet);
|
optionsBuilder.UseSnakeCaseNamingConvention(culture);
|
||||||
|
var plugin = new NamingConventionSetPlugin(optionsBuilder.Options);
|
||||||
|
plugin.ModifyConventions(conventionSet);
|
||||||
|
|
||||||
var builder = new ModelBuilder(conventionSet);
|
var modelBuilder = new ModelBuilder(conventionSet);
|
||||||
buildAction(builder);
|
builderAction(modelBuilder);
|
||||||
return builder.FinalizeModel();
|
return modelBuilder.FinalizeModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEntityType BuildEntityType(string entityTypeName, Action<EntityTypeBuilder> buildAction, CultureInfo cultureInfo = null)
|
public class SampleEntity
|
||||||
=> BuildModel(b => buildAction(b.Entity(entityTypeName)), cultureInfo).GetEntityTypes().Single();
|
{
|
||||||
|
public int SampleEntityId { get; set; }
|
||||||
|
public int SomeProperty { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
public class Blog
|
||||||
|
{
|
||||||
|
public int BlogId { get; set; }
|
||||||
|
public List<Post> Posts { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Post
|
||||||
|
{
|
||||||
|
public int PostId { get; set; }
|
||||||
|
public Blog Blog { get; set; }
|
||||||
|
public int BlogId { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Parent
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public int ParentProperty { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Child : Parent
|
||||||
|
{
|
||||||
|
public int ChildProperty { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Split1
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public int OneProp { get; set; }
|
||||||
|
public int Common { get; set; }
|
||||||
|
|
||||||
|
public Split2 S2 { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Split2
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public int TwoProp { get; set; }
|
||||||
|
public int Common { get; set; }
|
||||||
|
|
||||||
|
public Split1 S1 { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Owner
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public int OwnerProperty { get; set; }
|
||||||
|
public Owned Owned { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Owned
|
||||||
|
{
|
||||||
|
public int OwnedProperty { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,29 +1,30 @@
|
|||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using Microsoft.Data.Sqlite;
|
||||||
using Microsoft.EntityFrameworkCore.Diagnostics;
|
using Microsoft.EntityFrameworkCore.Diagnostics;
|
||||||
using Microsoft.EntityFrameworkCore.InMemory.Diagnostics.Internal;
|
using Microsoft.EntityFrameworkCore.Sqlite.Diagnostics.Internal;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
#pragma warning disable EF1001
|
|
||||||
|
|
||||||
// ReSharper disable once CheckNamespace
|
// ReSharper disable once CheckNamespace
|
||||||
namespace Microsoft.EntityFrameworkCore.TestUtilities
|
namespace Microsoft.EntityFrameworkCore.TestUtilities
|
||||||
{
|
{
|
||||||
public class InMemoryTestHelpers : TestHelpers
|
public class SqliteTestHelpers : TestHelpers
|
||||||
{
|
{
|
||||||
protected InMemoryTestHelpers()
|
protected SqliteTestHelpers()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public static InMemoryTestHelpers Instance { get; } = new();
|
public static SqliteTestHelpers Instance { get; } = new();
|
||||||
|
|
||||||
public override IServiceCollection AddProviderServices(IServiceCollection services)
|
public override IServiceCollection AddProviderServices(IServiceCollection services)
|
||||||
=> services.AddEntityFrameworkInMemoryDatabase();
|
=> services.AddEntityFrameworkSqlite();
|
||||||
|
|
||||||
public override void UseProviderOptions(DbContextOptionsBuilder optionsBuilder)
|
public override void UseProviderOptions(DbContextOptionsBuilder optionsBuilder)
|
||||||
=> optionsBuilder.UseInMemoryDatabase(nameof(InMemoryTestHelpers));
|
=> optionsBuilder.UseSqlite(new SqliteConnection("Data Source=:memory:"));
|
||||||
|
|
||||||
public override LoggingDefinitions LoggingDefinitions { get; } = new InMemoryLoggingDefinitions();
|
#pragma warning disable EF1001
|
||||||
|
public override LoggingDefinitions LoggingDefinitions { get; } = new SqliteLoggingDefinitions();
|
||||||
|
#pragma warning enable EF1001
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,11 +1,9 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Microsoft.EntityFrameworkCore;
|
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
|
||||||
{
|
{
|
||||||
@@ -66,25 +64,7 @@ namespace EFCore.NamingConventions.Internal
|
|||||||
public virtual void ProcessPropertyAdded(
|
public virtual void ProcessPropertyAdded(
|
||||||
IConventionPropertyBuilder propertyBuilder,
|
IConventionPropertyBuilder propertyBuilder,
|
||||||
IConventionContext<IConventionPropertyBuilder> context)
|
IConventionContext<IConventionPropertyBuilder> context)
|
||||||
{
|
=> RewriteColumnName(propertyBuilder);
|
||||||
var entityType = propertyBuilder.Metadata.DeclaringEntityType;
|
|
||||||
var property = propertyBuilder.Metadata;
|
|
||||||
|
|
||||||
propertyBuilder.HasColumnName(_namingNameRewriter.RewriteName(property.GetColumnBaseName()));
|
|
||||||
|
|
||||||
foreach (var storeObjectType in _storeObjectTypes)
|
|
||||||
{
|
|
||||||
var identifier = StoreObjectIdentifier.Create(entityType, storeObjectType);
|
|
||||||
if (identifier is null)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (property.GetColumnNameConfigurationSource(identifier.Value) == ConfigurationSource.Convention)
|
|
||||||
{
|
|
||||||
propertyBuilder.HasColumnName(
|
|
||||||
_namingNameRewriter.RewriteName(property.GetColumnName(identifier.Value)), identifier.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ProcessForeignKeyOwnershipChanged(IConventionForeignKeyBuilder relationshipBuilder, IConventionContext<bool?> context)
|
public void ProcessForeignKeyOwnershipChanged(IConventionForeignKeyBuilder relationshipBuilder, IConventionContext<bool?> context)
|
||||||
{
|
{
|
||||||
@@ -102,27 +82,11 @@ namespace EFCore.NamingConventions.Internal
|
|||||||
ownedEntityType.Builder.HasNoAnnotation(RelationalAnnotationNames.TableName);
|
ownedEntityType.Builder.HasNoAnnotation(RelationalAnnotationNames.TableName);
|
||||||
ownedEntityType.Builder.HasNoAnnotation(RelationalAnnotationNames.Schema);
|
ownedEntityType.Builder.HasNoAnnotation(RelationalAnnotationNames.Schema);
|
||||||
|
|
||||||
// Also need to reset all primary key properties
|
// We've previously set rewritten column names when the entity was originally added (before becoming owned).
|
||||||
foreach (var keyProperty in ownedEntityType.FindPrimaryKey().Properties)
|
// These need to be rewritten again to include the owner prefix.
|
||||||
|
foreach (var property in ownedEntityType.GetProperties())
|
||||||
{
|
{
|
||||||
keyProperty.Builder.HasNoAnnotation(RelationalAnnotationNames.ColumnName);
|
RewriteColumnName(property.Builder);
|
||||||
|
|
||||||
foreach (var storeObjectType in _storeObjectTypes)
|
|
||||||
{
|
|
||||||
var identifier = StoreObjectIdentifier.Create(ownedEntityType, storeObjectType);
|
|
||||||
if (identifier is null)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (keyProperty.GetColumnNameConfigurationSource(identifier.Value) == ConfigurationSource.Convention)
|
|
||||||
{
|
|
||||||
#pragma warning disable EF1001
|
|
||||||
// TODO: Using internal APIs to remove the override
|
|
||||||
var tableOverrides = (IDictionary<StoreObjectIdentifier, RelationalPropertyOverrides>)
|
|
||||||
keyProperty[RelationalAnnotationNames.RelationalOverrides];
|
|
||||||
tableOverrides.Remove(identifier.Value);
|
|
||||||
#pragma warning restore EF1001
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -135,40 +99,50 @@ namespace EFCore.NamingConventions.Internal
|
|||||||
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 (entityTypeBuilder.Metadata.FindPrimaryKey() is IConventionKey primaryKey)
|
if (entityType.FindPrimaryKey() is IConventionKey primaryKey)
|
||||||
{
|
{
|
||||||
primaryKey.Builder.HasName(_namingNameRewriter.RewriteName(primaryKey.GetDefaultName()));
|
if (entityType.BaseType is not null
|
||||||
|
&& entityType.GetTableName() != entityType.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);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
primaryKey.Builder.HasName(_namingNameRewriter.RewriteName(primaryKey.GetDefaultName()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var foreignKey in entityTypeBuilder.Metadata.GetForeignKeys())
|
foreach (var foreignKey in entityType.GetForeignKeys())
|
||||||
{
|
{
|
||||||
foreignKey.Builder.HasConstraintName(_namingNameRewriter.RewriteName(foreignKey.GetDefaultName()));
|
foreignKey.Builder.HasConstraintName(_namingNameRewriter.RewriteName(foreignKey.GetDefaultName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var index in entityTypeBuilder.Metadata.GetIndexes())
|
foreach (var index in entityType.GetIndexes())
|
||||||
{
|
{
|
||||||
index.Builder.HasDatabaseName(_namingNameRewriter.RewriteName(index.GetDefaultDatabaseName()));
|
index.Builder.HasDatabaseName(_namingNameRewriter.RewriteName(index.GetDefaultDatabaseName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oldAnnotation?.Value is null &&
|
if (annotation?.Value is not null &&
|
||||||
annotation?.Value is not null &&
|
entityType.FindOwnership() is IConventionForeignKey ownership &&
|
||||||
entityTypeBuilder.Metadata.FindOwnership() is IConventionForeignKey ownership &&
|
|
||||||
(string)annotation.Value != ownership.PrincipalEntityType.GetTableName())
|
(string)annotation.Value != ownership.PrincipalEntityType.GetTableName())
|
||||||
{
|
{
|
||||||
// An owned entity's table is being set explicitly - this is the trigger to undo table splitting (which is the default).
|
// An owned entity's table is being set explicitly - this is the trigger to undo table splitting (which is the default).
|
||||||
|
|
||||||
// When the entity became owned, we prefixed all of its properties - we must now undo that.
|
// When the entity became owned, we prefixed all of its properties - we must now undo that.
|
||||||
foreach (var property in entityTypeBuilder.Metadata.GetProperties()
|
foreach (var property in entityType.GetProperties()
|
||||||
.Except(entityTypeBuilder.Metadata.FindPrimaryKey().Properties)
|
.Except(entityType.FindPrimaryKey().Properties)
|
||||||
.Where(p => p.Builder.CanSetColumnName(null)))
|
.Where(p => p.Builder.CanSetColumnName(null)))
|
||||||
{
|
{
|
||||||
property.Builder.HasColumnName(_namingNameRewriter.RewriteName(property.GetDefaultColumnBaseName()));
|
RewriteColumnName(property.Builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We previously rewrote the owned entity's primary key name, when the owned entity was still in table splitting.
|
// We previously rewrote the owned entity's primary key name, when the owned entity was still in table splitting.
|
||||||
// Now that its getting its own table, rewrite the primary key constraint name again.
|
// Now that its getting its own table, rewrite the primary key constraint name again.
|
||||||
if (entityTypeBuilder.Metadata.FindPrimaryKey() is IConventionKey key)
|
if (entityType.FindPrimaryKey() is IConventionKey key)
|
||||||
{
|
{
|
||||||
key.Builder.HasName(_namingNameRewriter.RewriteName(key.GetDefaultName()));
|
key.Builder.HasName(_namingNameRewriter.RewriteName(key.GetDefaultName()));
|
||||||
}
|
}
|
||||||
@@ -224,5 +198,33 @@ namespace EFCore.NamingConventions.Internal
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void RewriteColumnName(IConventionPropertyBuilder propertyBuilder)
|
||||||
|
{
|
||||||
|
var property = propertyBuilder.Metadata;
|
||||||
|
var entityType = property.DeclaringEntityType;
|
||||||
|
|
||||||
|
// Remove any previous setting of the column name we may have done, so we can get the default recalculated below.
|
||||||
|
property.Builder.HasNoAnnotation(RelationalAnnotationNames.ColumnName);
|
||||||
|
|
||||||
|
// TODO: The following is a temporary hack. We should probably just always set the relational override below,
|
||||||
|
// but https://github.com/dotnet/efcore/pull/23834
|
||||||
|
#pragma warning disable 618
|
||||||
|
propertyBuilder.HasColumnName(_namingNameRewriter.RewriteName(property.GetColumnName()));
|
||||||
|
#pragma warning restore 618
|
||||||
|
|
||||||
|
foreach (var storeObjectType in _storeObjectTypes)
|
||||||
|
{
|
||||||
|
var identifier = StoreObjectIdentifier.Create(entityType, storeObjectType);
|
||||||
|
if (identifier is null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (property.GetColumnNameConfigurationSource(identifier.Value) == ConfigurationSource.Convention)
|
||||||
|
{
|
||||||
|
propertyBuilder.HasColumnName(
|
||||||
|
_namingNameRewriter.RewriteName(property.GetColumnName(identifier.Value)), identifier.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user