EFCore - 如何将多个导航属性设置为同一类型? [英] EFCore - How to have multiple navigation properties to the same type?

查看:27
本文介绍了EFCore - 如何将多个导航属性设置为同一类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的模型包含 Post 和 PostHistory 类,其中 Post 与 PostHistory 是一对多的关系.

My model contains the classes Post and PostHistory, where Post has a one-to-many relationship with 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 属性包含与该帖子相关的所有 PostVersion 的列表.CurrentVersion 和 PreviousVersion 属性都引用了该帖子历史记录中的特定版本(最有可能是最新版本和第一个版本).

The History property contains a list of all PostVersions related to that Post. The CurrentVersion and PreviousVersion properties both reference a perticlar version in that post history (most likley the most recent version and the first version).

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

My problem is that EF Core struggles to understand the relationship due to the CurrentVersion and OriginalVersion navigation properties. When I try to create a migration, I get this error message:

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 手动创建关系.

After that I tried to use the Fluent API to create the relationships manually.

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 code-first 中创建这种关系?

Is it possible to create this kind of relationship in EF Core code-first?

推荐答案

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

Edit I did some changes, you cannot reference same property in multiple relationships. Therefore i had to use foreign keys for mappings. PostVersion has only one Post reference as you required.

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

<小时>

原创您需要为第二个关系指定其他属性


Original You need to specify additional property for that second relationship

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

这篇关于EFCore - 如何将多个导航属性设置为同一类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆