EF核心一对多关系HasOne().WithMany()vs HasMany().WithOne()

Soo*_*ban 19 c# entity-framework asp.net-core

假设我有以下两种型号:

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }

    public List<Post> Posts { get; set; }
}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    public Blog Blog { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

现在,如果我想在DbContext中配置模型关系,那么之间有什么区别:

modelBuilder.Entity<Post>()
            .HasOne(p => p.Blog)
            .WithMany(b => b.Posts);
Run Code Online (Sandbox Code Playgroud)

modelBuilder.Entity<Blog>()
            .HasMany(b => b.Posts)
            .WithOne(p => p.blog);
Run Code Online (Sandbox Code Playgroud)

如果有差异,那是什么?我应该写两个还是只写其中一个?

作为旁注:我是否必须定义外键?根据我对数据库的了解,您无法在没有外键的情况下创建关系,但EF不要求您拥有外键字段.那么EF如何在不知道外键的情况下处理关系呢?它会导致性能下降还是错误?

H. *_*rzl 10

你是对的,你可以在DbContext中创建关系而不需要数据库中的外键.

也:

WithOne:一对一关系在两侧都有引用导航属性.它们遵循与一对多关系相同的约定,但在外键属性上引入了唯一索引,以确保只有一个依赖关系与每个主体相关.

多对多:尚不支持没有实体类来表示连接表的关系.但是,您可以通过包含连接表的实体类并映射两个单独的一对多关系来表示多对多关系.

您只需要定义一个关系,因为在某些情况下,您将为父子创建一个没有导航属性(一个或集合)的关系.

对于您的示例:您为Blog - > Posts添加关系,因为您在两个对象中都有导航属性,这两行以相同的方式但以不同的方式:

  • 博客 - >帖子(家长 - >孩子)
  • 帖子 - >博客(儿童 - >父母)

  • "你可以在DbContext中创建关系而不需要数据库中的外键." 这是不正确的.EF将引入一个阴影属性,该属性不在您的模型中,但将在数据库中. (3认同)
  • 所以你是说两种方法之间没有区别,我可以以相同的方式使用模型吗?但是使用HasOne()。WithMany更好? (2认同)