Отображение собственного типа в отдельной таблице - PullRequest
1 голос
/ 24 марта 2020

У меня типичные отношения один-к-одному, когда одна сторона владеет другой. Собственная сторона - это слабая сущность, у которой нет собственного идентификатора в базе данных; вместо этого каждая запись идентифицируется владельцем ПК. Позвольте мне проиллюстрировать это примером, где video записи могут иметь связанную transcription запись.

video (id, description, storage_path)
transcription (video_id, text)

Видеозаписи имеют свою собственную жизнь. У некоторых из них есть доступная транскрипция; большинство не Моя проблема - выяснить, как правильно смоделировать это с EF Core 3.1. Для отображения video у меня есть что-то вроде:

public void Configure(EntityTypeBuilder<Video> builder)
{
    // ...
    builder.OwnsOne(video => video.Transcription).WithOwner();
}

Как мне отобразить сторону transcription? Когда я попытался создать для него отдельное сопоставление, я получил сообщение о том, что transcription нельзя сопоставить как не принадлежащий .

Ниже приведены соответствующие биты классов сущностей и код первый ORM (с использованием FluentMigrator ).

Видео

public class Video
{
    public int Id { get; set; }
    // ...
    public Transcription Transcription { get; set; }
}
public class VideoTable : Migration
{
    public override void Up()
    {
        Create.Table("videos")
            .WithColumn("id").AsInt64().PrimaryKey().Identity()
            // ...
    }
}
public class VideoMap : IEntityTypeConfiguration<Video>
{
    public void Configure(EntityTypeBuilder<Video> builder)
    {
        builder.ToTable("videos");
        builder.Property(v => v.Id).HasColumnName("id").IsRequired();
        // ...
        builder.OwnsOne(v => v.Transcription, tbuilder => {
            tbuilder.WithOwner().HasForeingKey("VideoId");
            tbuilder.Property("VideoId").HasColumnName("video_id");
            // ...
            tbuilder.ToTable("transcriptions");
        });
    }
}

Транскрипция

public class Transcription
{
    public int VideoId { get; set; }
    // ...
}
public class TranscriptionTable : Migration
{
    public override void Up()
    {
        Create.Table("transcriptions")
            .WithColumn("video_id").AsInt64().PrimaryKey()
            // ...

        Create.ForeignKey("fk_video_transcription")
            .FromTable("transcriptions").ForeignColumn("video_id")
            .ToTable("videos").PrimaryColumn("id");
    }
}

Что я пропускаю?

Примечание. Мне известно, что подобные отношения могут быть реализованы с полями собственных объектов, включенными в таблицу-владелец. Однако есть практические причины, по которым их следует хранить отдельно.

1 Ответ

1 голос
/ 24 марта 2020

Собственные типы всегда (возможно, могут быть) настроены через их сущность-владелец и, более конкретно, через их собственный конструктор, возвращаемый методом OwnsOne или предоставляемый в качестве аргумента аргумента Action<T> метода OwnsOne построителя сущностей владельца.

Обратите внимание, что вы уже используете построитель сущностей, которым владеете, для вызова .WithOwner(), который, в свою очередь, используется для настройки отношений между владельцем и владельцем. Для принадлежащих только связанных конфигураций, таких как свойства, имена столбцов, таблица и т. Д. c. вы используете методы владения соответствующим строителем.

например

builder.OwnsOne(video => video.Transcription, ownedBuilder =>
{
    ownedBuilder.WithOwner()
        .HasForeignKey("VideoId");

    ownedBuilder.Property("VideoId")
        .HasColumnName("video_id");

    ownedBuilder.ToTable("Transcription");
});
...