【问题标题】:EFCore - How to have multiple navigation properties to the same type?EFCore - 如何将多个导航属性设置为同一类型?
【发布时间】:2019-05-16 11:33:23
【问题描述】:

我的模型包含 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 的列表。 CurrentVersion 和 PreviousVersion 属性都引用了该帖子历史记录中的特定版本(最有可能是最新版本和第一个版本)。

我的问题是,由于 CurrentVersion 和 OriginalVersion 导航属性,EF Core 难以理解这种关系。当我尝试创建迁移时,我收到以下错误消息:

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 代码优先中创建这种关系?

【问题讨论】:

  • 正确的方法是什么?
  • 能否请您给我一个关于设计的哪一部分错误的一般指示?
  • @TanvirArjel 你是不是疯了要求远程访问?

标签: c# asp.net .net entity-framework entity-framework-core


【解决方案1】:

编辑 我做了一些更改,您不能在多个关系中引用相同的属性。因此我不得不使用外键进行映射。 PostVersion 只有一个您需要的 Post 参考。

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);

【讨论】:

  • PostVersion 应该只引用一个帖子。
  • 我今天有时间进一步研究并重新测试 - 检查我的编辑
  • 按照您的回答后,我能够创建迁移,但我仍然无法更新数据库。在更新这些关系之前,我必须为每个关系显式设置OnDelete 行为,即便如此,它也无法为 Post 和 PostVersion 创建表。我不知道这是否是一个单独的问题,而且由于您确实解决了我最初遇到的问题,我很高兴将此作为公认的答案。无论如何,我已经改变了我的模型以避免这种讨厌的关系问题,所以我不关心在这方面进一步发展。感谢您的帮助。
  • 可以在fluent定义中指定onDelete行为.WillCascadeOnDelete(false/ true);
猜你喜欢
  • 2021-06-08
  • 1970-01-01
  • 2023-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多