【问题标题】:Relationship errors while applying migrations - EF Core 5.0应用迁移时出现关系错误 - EF Core 5.0
【发布时间】:2021-05-17 10:14:43
【问题描述】:

我正在尝试模拟由 3 个实体组成的场景,即 - UserPostComment

user 可以在该帖子上创作post,另一个user 或相同的user 可以comment

因此User 实体可以在其下关联多个帖子。并且Comment 实体可以有多个 cmet 与不同用户的单个帖子相关联。

我正在尝试使用 EF Core 5.0 在我的模型上应用迁移,但出现错误 -

'Post' 和 'User.Comments' 之间以及 'Post.Author' 和 'User' 之间的关系都可以使用 {'AuthorId'} 作为外键。

要解决此问题,请在至少一个关系的“OnModelCreating”中明确配置外键属性。


这里是模型类(用户、帖子和评论)-

public class BaseEntity<TKey>
{
    public TKey Id { get; set; }
    public DateTime CreatedAt { get; set; }
    public DateTime? UpdatedAt { get; set; }
}

public class User : BaseEntity<int>
{
    [Required]
    [MaxLength(256)]
    public string Username { get; set; }

    [Required]
    [EmailAddress]
    [MaxLength(256)]
    public string Email { get; set; }

    [Required]
    [DataType(DataType.Password)]
    public string Password { get; set; }
    
    public IReadOnlyList<Post> Posts { get; set; }
    
    public IReadOnlyList<Comment> Comments { get; set; }
}

public class Post : BaseEntity<int>
{
    [Required]
    [MaxLength(200)]
    public string Title { get; set; }

    [Required]
    [MaxLength(512)]
    public string Content { get; set; }

    public User Author { get; set; }
}

public class Comment : BaseEntity<int>
{
    [Required]
    [MaxLength(512)]
    public string Body { get; set; }

    public User Author { get; set; }
    
    public Post Post { get; set; }
}

这里是上下文类 -

public class BlogContext : DbContext
{
    public BlogContext(DbContextOptions options): base(options)
    {
    }

    public DbSet<User> Users { get; set; }
    public DbSet<Post> Posts { get; set; }
    public DbSet<Comment> Comments { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder
            .Entity<User>()
            .HasIndex(x => x.Username)
            .IsUnique();

        modelBuilder
            .Entity<User>()
            .HasIndex(x => x.Email)
            .IsUnique();

        modelBuilder
           .Entity<User>()
           .HasMany(u => u.Posts)
           .WithOne()
           .OnDelete(DeleteBehavior.Cascade);

        modelBuilder
           .Entity<User>()
           .HasMany(u => u.Comments)
           .WithOne()
           .OnDelete(DeleteBehavior.Cascade);

        modelBuilder
            .Entity<Post>()
            .HasOne(p => p.Author)
            .WithMany();

        modelBuilder
            .Entity<Comment>()
            .HasOne(c => c.Post)
            .WithMany(p => p.Comments);
          
        modelBuilder
            .Entity<Comment>()
            .HasOne(c => c.Author)
            .WithMany();

        base.OnModelCreating(modelBuilder);
    }
}

任何人都可以纠正错误并提供最佳实践来模拟这种情况

【问题讨论】:

  • 您需要在表中添加主键,并在 Post 和 Comment 中添加外键
  • @d0little 默认情况下,Id 不是主键,因为我已将该代码移至 BaseEntity 类并且实体框架不会为外键生成影子属性?
  • 图片中缺少某些东西。 Author 这里public Author Author { get; set; } 是什么?
  • @IvanStoev Author 分别是PostComment 的导航属性,对于Post,它将指示哪个User 添加了Post,对于Comment,它将指出哪个用户发表了评论
  • 看起来您没有“配对”正确形成关系的导航属性。你应该有User.Posts Post.AuthorUser.Comments Comment.AuthorPost.Comments Comment.Post,即3个关系,而你基本上配置了6个关系。为什么不删除所有这些 Has / With 并让 EF Core 默认配对它们,这对我有用?

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


【解决方案1】:

您必须添加 UserId 和 PostId 键

public class Post : BaseEntity<int>
{

    [Required]
    [MaxLength(200)]
    public string Title { get; set; }

    [Required]
    [MaxLength(512)]
    public string Content { get; set; }

    public int UserId{ get; set; }

    [ForeignKey(nameof(UserId))]
    [InverseProperty(nameof(User.Posts))]
    public User Author { get; set; }

     public ICollection<Comment> Comments { get; set; }
}

public class Comment : BaseEntity<int>
{
    [Required]
    [MaxLength(512)]
    public string Body { get; set; }

    public int UserId{ get; set; }
    [ForeignKey(nameof(UserId))]
    [InverseProperty(nameof(User.Comments))]
    public User Author { get; set; }
    
   public int PostId{ get; set; }
    [ForeignKey(nameof(PostId))]
    [InverseProperty(nameof(Post.Comments))]
    public Post CommentPost { get; set; }
}

【讨论】:

  • 这种情况下不需要流畅的配置?
  • 不,你应该不需要任何
  • 让我试试这个
  • 不,收到错误The [InverseProperty] attribute on property 'Comment.Author' is not valid. The property 'User.Comments' is not a valid navigation on the related type 'User'. Ensure that the property exists and is a valid reference or collection navigation.
  • 很抱歉,您应该询问 EF 核心团队。我什至之前给他们发过电子邮件。 nameof(Post.Comments) 没有构造函数就无法工作。在这种情况下,您只能使用“评论”。
猜你喜欢
  • 1970-01-01
  • 2022-01-15
  • 1970-01-01
  • 2016-12-29
  • 2021-12-29
  • 2016-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多