我们是否必须在两个实体上配置HasXXX和WithYYY(而不是仅在其中一个实体上)才能建立关系

本文关键字:实体 在其中 关系 建立 一个 HasXXX 是否 两个 我们 配置 WithYYY | 更新日期: 2023-09-27 18:22:31

假设我有两个实体,如下所示:

class Blog
{
    public Blog()
    {
        Posts = new HashSet<Post>();
    }
    public int Id { get; set; }
    // other properties go here
    public ICollection<Post> Posts { get; set; }
}
class Post
{
    public int Id { get; set; }
    //other properties go here
    public int FKBlogId { get; set; }
    public Blog Blog { get; set; }
}

由于每个帖子都属于一个博客,并且每一个博客可以有零个或多个帖子

我在网上没有找到一篇文章,讨论我们是否需要在两个实体上配置关系,如下所示。

class Context : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
    public DbSet<Post> Posts { get; set; }
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Blog>()
            .HasMany(b => b.Posts)
            .WithRequired(p => p.Blog)
            .HasForeignKey(p => p.FKBlogId);

        modelBuilder.Entity<Post>()
            .HasRequired(p => p.Blog)
            .WithMany(b => b.Posts)
            .HasForeignKey(p => p.FKBlogId);
    }
}

我们必须在两个实体上配置关系吗?换言之,以下其中一项是否足够?

    modelBuilder.Entity<Blog>()
        .HasMany(b => b.Posts)
        .WithRequired(p => p.Blog)
        .HasForeignKey(p => p.FKBlogId);

    modelBuilder.Entity<Post>()
        .HasRequired(p => p.Blog)
        .WithMany(b => b.Posts)
        .HasForeignKey(p => p.FKBlogId);

我已经用其中一个进行了测试,我没有注意到它们之间有任何区别。你能确认一下我的理解是否正确吗?

我们是否必须在两个实体上配置HasXXX和WithYYY(而不是仅在其中一个实体上)才能建立关系

两者中的一个就足够了,哪一个无关紧要。

测试项目(更多针对Fred Wilson),控制台项目,参考EntityFramework.dll(4.1或4.2):

using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
namespace EFMappingTest
{
    class Blog
    {
        public Blog()
        {
            Posts = new HashSet<Post>();
        }
        public int Id { get; set; }
        // other properties go here
        public ICollection<Post> Posts { get; set; }
    }
    class Post
    {
        public int Id { get; set; }
        //other properties go here
        public int FKBlogId { get; set; }
        public Blog Blog { get; set; }
    }
    class Context : DbContext
    {
        public DbSet<Blog> Blogs { get; set; }
        public DbSet<Post> Posts { get; set; }
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            // Block 1
            modelBuilder.Entity<Blog>()
                .HasMany(b => b.Posts)
                .WithRequired(p => p.Blog)
                .HasForeignKey(p => p.FKBlogId);
            // End Block 1
            // Block 2
            modelBuilder.Entity<Post>()
                .HasRequired(p => p.Blog)
                .WithMany(b => b.Posts)
                .HasForeignKey(p => p.FKBlogId);
            // End Block 2
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            using (var context = new Context())
            {
                var blogs = context.Blogs
                    .Select(b => new
                    {
                        BlogId = b.Id,
                        Posts = b.Posts.Select(p => new
                        {
                            Id = p.Id
                        })
                    })
                    .ToList();
            }
        }
    }
}

此配置、注释掉"Block 2"时的配置和注释掉"Block 1"时的设置-这三种配置都创建了相同的数据库模式和关系(除了数据库中FK约束的名称,可以是Blog_PostsPosts_Blog)。

示例查询适用于所有三种情况。