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

UseSnakeCaseNamingConvention() creates unnecessary foreign key for owned type when using TPT mapping strategy #191

Open
Gbsyi opened this issue Mar 5, 2023 · 0 comments
Labels
bug Something isn't working
Milestone

Comments

@Gbsyi
Copy link

Gbsyi commented Mar 5, 2023

When I create an own-type class and try to configure it using OwnsOne(), ef creates an unnecessary foreign key to the parent table. If I remove UseSnakeCaseNamingConvention(), there is no foreign key for own type.

How to reproduce

Link to my repo with bug: https://github.com/Gbsyi/EfTpt
There are some snippets from that repo.

Models:

public abstract class Transport
{
    public Guid Id { get; set; }

    protected Transport()
    {
    }
}

public class Speed
{
    public int Value { get; }
}

public class Car : Transport
{
    public Speed Speed { get; set; }
}

Configuration:

modelBuilder.Entity<Transport>(e =>
        {
            e.HasKey(x => x.Id);
            e.UseTptMappingStrategy();
        });

        modelBuilder.Entity<Car>(e =>
        {
            e.OwnsOne(x => x.Speed, bld =>
            {
                bld.Property(x => x.Value)
                    .HasColumnName("speed");
            });
        });

What it creates:

Migration:

migrationBuilder.CreateTable(
                name: "Cars",
                columns: table => new
                {
                    id = table.Column<Guid>(type: "uuid", nullable: false),
                    speed = table.Column<int>(type: "integer", nullable: false)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_Cars", x => x.id);
                    table.ForeignKey(
                        name: "fk_cars_cars_id",
                        column: x => x.id,
                        principalTable: "Transports",
                        principalColumn: "id",
                        onDelete: ReferentialAction.Cascade);
                    table.ForeignKey(
                        name: "fk_cars_transports_id",
                        column: x => x.id,
                        principalTable: "Transports",
                        principalColumn: "id",
                        onDelete: ReferentialAction.Cascade);
                });

Migration.Designer:

modelBuilder.Entity("EfTpt.Ef.Models.Car", b =>
                {
                    b.HasOne("EfTpt.Ef.Models.Transport", null)
                        .WithOne()
                        .HasForeignKey("EfTpt.Ef.Models.Car", "Id")
                        .OnDelete(DeleteBehavior.Cascade)
                        .IsRequired()
                        .HasConstraintName("fk_cars_transports_id");

                    b.OwnsOne("EfTpt.Ef.Types.Speed", "Speed", b1 =>
                        {
                            b1.Property<Guid>("CarId")
                                .HasColumnType("uuid")
                                .HasColumnName("id");

                            b1.Property<int>("Value")
                                .HasColumnType("integer")
                                .HasColumnName("speed");

                            b1.HasKey("CarId");

                            b1.ToTable("Cars");

                            b1.WithOwner()
                                .HasForeignKey("CarId")
                                .HasConstraintName("fk_cars_cars_id");
                        });

                    b.Navigation("Speed")
                        .IsRequired();
                });

What it will create if I'll remove UseSnakeCaseNamingConvention()

Migration:

migrationBuilder.CreateTable(
                name: "Cars",
                columns: table => new
                {
                    Id = table.Column<Guid>(type: "uuid", nullable: false),
                    speed = table.Column<int>(type: "integer", nullable: false)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_Cars", x => x.Id);
                    table.ForeignKey(
                        name: "FK_Cars_Transports_Id",
                        column: x => x.Id,
                        principalTable: "Transports",
                        principalColumn: "Id",
                        onDelete: ReferentialAction.Cascade);
                });

Migration.Designer:

modelBuilder.Entity("EfTpt.Ef.Models.Car", b =>
                {
                    b.HasOne("EfTpt.Ef.Models.Transport", null)
                        .WithOne()
                        .HasForeignKey("EfTpt.Ef.Models.Car", "Id")
                        .OnDelete(DeleteBehavior.Cascade)
                        .IsRequired();

                    b.OwnsOne("EfTpt.Ef.Types.Speed", "Speed", b1 =>
                        {
                            b1.Property<Guid>("CarId")
                                .HasColumnType("uuid");

                            b1.Property<int>("Value")
                                .HasColumnType("integer")
                                .HasColumnName("speed");

                            b1.HasKey("CarId");

                            b1.ToTable("Cars");

                            b1.WithOwner()
                                .HasForeignKey("CarId");
                        });

                    b.Navigation("Speed")
                        .IsRequired();
                });

Provider and version information

EF Core version: 7.0.3
Database provider: Npgsql.EntityFrameworkCore.PostgreSQL 7.0.3
Target framework: NET 7.0
EFCore.NamingConventions version: 7.0.2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants