EF核心-同一对实体上的一对多和多对一关系

时间:2020-05-13 02:04:16

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

我在定义两个实体之间的关系时遇到问题。

我要实现的目标:

  1. 我希望与用户建立某种媒体文件(视频/图像/文件) 评论。

  2. 用户注释也可以具有多个媒体文件。

我正在使用.net core 3.1和最新的EF Core

课程:

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

    // can belong to media file but in future this comment could also belong to say.. 
    // feed post, some other in-app activity
    public Guid? ParentMediaId { get; set; }
    public virtual MediaFile ParentMedia { get; set; }

    // can contain multiple media
    public virtual ICollection<MediaFile> CommentMediaCollection { get; set; } = new HashSet<MediaFile>();
}

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

    // this media file can belong to comment, but also number of other entities in app
    public Guid? ParentCommentId { get; set; }
    public virtual Comment ParentComment { get; set; }

    // can also have multiple comments
    public virtual ICollection<Comment> Comments { get; set; } = new HashSet<Comment>();
}

配置文件:

评论配置文件

            builder
            .HasMany(x => x.CommentMediaCollection)
            .WithOne(x => x.ParentComment)
            .HasForeignKey(x => x.ParentCommentId)
            .OnDelete(DeleteBehavior.Cascade);

        builder
            .HasOne(x => x.ParentMedia)
            .WithMany(x => x.Comments)
            .HasForeignKey(x => x.ParentMediaId)
            .OnDelete(DeleteBehavior.SetNull)
            .IsRequired(false);

媒体配置文件:

            builder
            .HasOne(x => x.ParentComment)
            .WithMany(x => x.CommentMediaCollection)
            .HasForeignKey(x => x.ParentCommentId)
            .OnDelete(DeleteBehavior.SetNull)
            .IsRequired(false);

        builder
            .HasMany(x => x.Comments)
            .WithOne(x => x.ParentMedia)
            .HasForeignKey(x => x.ParentMediaId)
            .OnDelete(DeleteBehavior.Cascade);

问题:

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

网上有大量建议,但全部归结为对我来说配置...似乎还可以吗?

干杯!

1 个答案:

答案 0 :(得分:0)

1。我希望拥有某种带有用户评论的媒体文件(视频/图像/文件)。

2。用户注释也可以具有多个媒体文件。

根据您的要求,您需要配置多对多关系。

这是一个工作示例:

1。型号:

public class Comment
{
    public Guid Id { get; set; }
    //other properties

    public virtual ICollection<CommentMediaFile> CommentMediaFiles { get; set; } 
}

public class MediaFile
{
    public Guid Id { get; set; }
    //other properties

    public virtual ICollection<CommentMediaFile> CommentMediaFiles { get; set; } 
}
public class CommentMediaFile
{
    public Guid CommentId { get; set; }
    public Comment Comment { get; set; }
    public Guid MediaFileId { get; set; }
    public MediaFile MediaFile { get; set; }
}

2.DbContext:

public class MyContext : DbContext
{
    public MyContext(DbContextOptions<MyContext> options)
        : base(options)
    {
    }
    public DbSet<Comment> Comments { get; set; }
    public DbSet<MediaFile> MediaFiles { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<CommentMediaFile>()
            .HasKey(t => new { t.CommentId, t.MediaFileId });

        modelBuilder.Entity<CommentMediaFile>()
            .HasOne(pt => pt.Comment)
            .WithMany(p => p.CommentMediaFiles)
            .HasForeignKey(pt => pt.CommentId);

        modelBuilder.Entity<CommentMediaFile>()
            .HasOne(pt => pt.MediaFile)
            .WithMany(t => t.CommentMediaFiles)
            .HasForeignKey(pt => pt.MediaFileId);
    }
}

参考:

https://docs.microsoft.com/en-us/ef/core/modeling/relationships?tabs=fluent-api%2Cfluent-api-simple-key%2Csimple-key#many-to-many