EFCore - Как иметь несколько навигационных свойств для одного типа? - PullRequest
0 голосов
/ 15 декабря 2018

Моя модель содержит классы Post и PostHistory, где Post имеет отношение один-ко-многим с PostHistory.

class Post
{
    public int Id { get; set; }

    public PostVersion CurrentVersion { get; set; }
    public PostVersion OriginalVersion { get; set; }
    public IList<PostVersion> History { get; set; }
}

class PostVersion
{
    public int Id { get; set; }
    public Post Post { get; set; }

    public string Title { get; set; }
    public string Body { get; set; }
}

Свойство History содержит список всех PostVersions, связанных с этим Post.Свойства CurrentVersion и PreviousVersion ссылаются на версию perticlar в этой истории публикаций (наиболее вероятно, самую последнюю версию и первую версию).

Моя проблема заключается в том, что EF Core пытается понять взаимосвязь из-за CurrentVersion и OriginalVersionнавигационные свойства.Когда я пытаюсь создать миграцию, я получаю следующее сообщение об ошибке:

Unable to determine the relationship represented by navigation property 'Post.CurrentVersion' of type 'PostVersion'. Either manually configure the relationship, or ignore this property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.

После этого я пытался использовать Fluent API для создания отношений вручную.

protected override void OnModelCreating(ModelBuilder builder)
{
    base.OnModelCreating(builder);

    builder.Entity<Post>()
        .HasMany(x => x.History)
        .WithOne(x => x.Post);
    builder.Entity<Post>()
        .HasOne(x => x.CurrentVersion)
        .WithOne(x => x.Post);
    builder.Entity<Post>()
        .HasOne(x => x.OriginalVersion)
        .WithOne(x => x.Post);
}

Но создалдругая ошибка:

Cannot create a relationship between 'PostVersion.Post' and 'Post.CurrentVersion', because there already is a relationship between 'Post.History' and 'PostVersion.Post'. Navigation properties can only participate in a single relationship.

Возможно ли создать такого рода отношения в коде EF Core в первую очередь?

1 Ответ

0 голосов
/ 15 декабря 2018

Редактировать Я внес некоторые изменения, вы не можете ссылаться на одно и то же свойство в нескольких отношениях.Поэтому мне пришлось использовать внешние ключи для сопоставлений. PostVersion имеет только одну публикацию ссылку, как вам нужно.

public class Post
{
    public Guid Id { get; set; }

    public Guid CurrentVersionId { get; set; }
    public PostVersion CurrentVersion { get; set; }
    public Guid OriginalVersionId { get; set; }
    public PostVersion OriginalVersion { get; set; }
    public IList<PostVersion> History { get; set; }
}

public class PostVersion
{
    public Guid Id { get; set; }
    public Guid PostId { get; set; }

    public Post Post { get; set; }

    public string Title { get; set; }
    public string Body { get; set; }
}

modelBuilder.Entity<Post>()
    .HasOne(x => x.CurrentVersion)
    .WithOne()
    .HasForeignKey<Post>(p => p.CurrentVersionId);
modelBuilder.Entity<Post>()
    .HasOne(x => x.OriginalVersion)
    .WithOne()
    .HasForeignKey<Post>(p => p.OriginalVersionId);

modelBuilder.Entity<Post>()
    .HasMany(x => x.History)
    .WithOne(p => p.Post)
    .HasForeignKey(pv => pv.PostId);

Оригинал Вам необходимо указать дополнительное свойство для этой секундыотношения

public class Post
{
    public Guid Id { get; set; }

    public PostVersion CurrentVersion { get; set; }
    public PostVersion OriginalVersion { get; set; }
    public IList<PostVersion> History { get; set; }
}

public class PostVersion
{
    public Guid Id { get; set; }
    public Post Post { get; set; }
    public Post SecondPost { get; set; }
    public Post ThirdPost { get; set; }

    public string Title { get; set; }
    public string Body { get; set; }
}


 modelBuilder.Entity<Post>()
            .HasOne(x => x.CurrentVersion)
            .WithOne(x => x.Post);
 modelBuilder.Entity<Post>()
            .HasOne(x => x.OriginalVersion)
            .WithOne(x => x.SecondPost);
 modelBuilder.Entity<Post>()
            .HasMany(x => x.History)
            .WithOne(x => x.ThirdPost);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...