Ядро Entity Framework OwnsOne создает отдельные таблицы, а не добавляет свойства в ту же таблицу, как ожидалось - PullRequest
0 голосов
/ 05 сентября 2018

Я думал, что основные типы Entity Framework по умолчанию добавляются в ту же таблицу, что и их владелец. Но я не вижу этого в миграции.

Кто-нибудь подскажет мне здесь?

Есть ли способ получить желаемую миграцию со свойствами Name, добавленными непосредственно в таблицу 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 миграций добавить 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);
            });
        );
    }
}

Ответы [ 2 ]

0 голосов
/ 18 февраля 2019

Попробуйте что-то вроде следующего:

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);
        });
}
0 голосов
/ 05 сентября 2018

Я создал это сам невольно с этим кодом конфигурации

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;
       }
   }
}    
...