实体框架核心OwnsOne创建单独的表,而不是向预期的同一表添加属性

问题描述 投票:1回答:2

我认为默认情况下,Entity Framework Core Owned Types会被添加到与其所有者相同的表中。但是我没有在迁移中看到这一点。

有人会在这里提醒我吗?

有没有办法通过名称属性直接添加到Person表来获得所需的迁移?

public class Person
{
    public Name Name { get; set; }
}

public class Name
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

public class PersonConfiguration : IEntityTypeConfiguration<Person>
{
    public void Configure(EntityTypeBuilder<Person> person)
    {
          person.OwnsOne(p => p.Name);
    }
}

dotnet ef migrations添加了DidNotSeeThatComing结果

public partial class DidNotSeeThatComing : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.CreateTable(
            name: "Name",
            columns: table => new
            {
                FirstName = table.Column<string>(type: "varchar", nullable: true),
                LastName = table.Column<string>(type: "varchar", nullable: true),
                PersonId = table.Column<Guid>(nullable: false)
            },
            constraints: table =>
            {
                table.PrimaryKey("PK_Name", x => x.PersonId);
                table.ForeignKey(
                    name: "FK_Name_Person_PersonId",
                    column: x => x.PersonId,
                    principalTable: "Person",
                    principalColumn: "Id",
                    onDelete: ReferentialAction.Cascade);
            });
        );
    }
}
entity-framework core ef-migrations ef-core-2.1 owned-types
2个回答
2
投票

我在这个配置代码中不自觉地创建了这个

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
   base.OnModelCreating(modelBuilder);
   foreach (var entity in modelBuilder.Model.GetEntityTypes())
   {
       entity.Relational().TableName = entity.Name;
   }
}

这是我正在使用的解决方法

[Owned] // Microsoft.EntityFrameworkCore
public class Name { ... }

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
   base.OnModelCreating(modelBuilder);
   foreach (var entity in modelBuilder.Model.GetEntityTypes())
   {
       if(!entity.ClrType.GetCustomAttributes().OfType<OwnedAttribute>().Any())
       {
            entity.Relational().TableName = entity.Name;
       }
   }
}    

0
投票

尝试以下内容:

public class Person
{
    public Guid Id { get; set; }
    public Name Name { get; set; }
}

public class Name
{
    public Guid Id { get; set; }
    public Guid PersonId {get;set;}
    public Person Person { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

public class PersonConfiguration : IEntityTypeConfiguration<Person>
{
    public void Configure(EntityTypeBuilder<Person> person)
    {
        person.OwnsOne(p => p.Name,
            nCls =>
            {
                nCls.HasOne(n => n.Person);
                nCls.HasKey(n => new {n.Id, n.PersonId});
                nCls.HasForeignKey(m => m.PersonId);
                nCls.ToTable(nCls.OwnedEntityType.ClrType.Name);
            }
        );
    }
}

这应该会让你这样:

protected override void Up(MigrationBuilder migrationBuilder)
{
// the table names are lower case because my convention is to generate all names in snake_case

    migrationBuilder.CreateTable(
        name: "persons",
        columns: table => new
        {
            id = table.Column<Guid>(nullable: false)
        },
        constraints: table =>
        {
            table.PrimaryKey("pk_persons", x => x.id);
        });

    migrationBuilder.CreateTable(
        name: "name",
        columns: table => new
        {
            id = table.Column<Guid>(nullable: false),
            person_id = table.Column<Guid>(nullable: false),
            first_name = table.Column<string>(maxLength: 256, nullable: true),
            last_name = table.Column<string>(maxLength: 256, nullable: true)
        },
        constraints: table =>
        {
            table.PrimaryKey("pk_name", x => new { x.id, x.person_id });
            table.ForeignKey(
                name: "fk_name_persons_person_id",
                column: x => x.person_id,
                principalTable: "persons",
                principalColumn: "id",
                onDelete: ReferentialAction.Cascade);
        });
}
© www.soinside.com 2019 - 2024. All rights reserved.