EF核心一对多关系HasOne(). withmany () vs HasMany(). withone()

本文关键字:vs HasMany withone withmany 核心 关系 HasOne EF 一对多 | 更新日期: 2023-09-27 18:09:30

假设我有以下两个模型:

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

现在,如果我想配置DbContext中的模型关系,是否有以下区别:

modelBuilder.Entity<Post>()
            .HasOne(p => p.Blog)
            .WithMany(b => b.Posts);

modelBuilder.Entity<Blog>()
            .HasMany(b => b.Posts)
            .WithOne(p => p.blog);

如果有区别,是什么?我应该写两个还是只写一个?

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

EF核心一对多关系HasOne(). withmany () vs HasMany(). withone()

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

:

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

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

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

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

  • Blog -> Posts (Parent -> child)
  • Posts -> Blog (Child -> Parent)

您可以在没有外键属性的情况下定义模型。然而,实体框架将引入一个阴影属性,它将在数据库中。

根据文档:

虽然建议在依赖实体类中定义外键属性,但这不是必需的。如果没有找到外键属性,则会引入一个名为<navigation property name><principal key property name>的影子外键属性(有关更多信息,请参阅影子属性)。