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

时间:2016-09-30 00:38:00

标签: 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; }
}

现在,如果我想在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如何在不知道外键的情况下处理关系呢?它会导致性能下降还是错误?

2 个答案:

答案 0 :(得分:10)

你是对的,你可以在DbContext中创建没有外键的关系。

此外:

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

尚未支持没有实体类来表示连接表的

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

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

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

  • 博客 - &gt;帖子(父母 - &gt;孩子)
  • 帖子 - &gt;博客(儿童 - &gt;父母)

答案 1 :(得分:2)

您可以在没有外键属性的情况下定义模型。但是,Entity Framework将引入一个shadow属性,它将存在于数据库中。

根据documentation

  

虽然建议在依赖实体类中定义外键属性,但不是必需的。如果未找到外键属性,则将引入名为function promises() { const proms = requests.map(service => { service().then(() => ({ success: true })) .catch(() => ({ success: false, errorCode: 'some error' })) }) Promise.all(proms) } someType: { name: 'SomeType', resolve: async val => { const resp = await promises(); // extract the errors in push them to GraphQL errors // display the rest of the data } } 的影子外键属性(有关详细信息,请参阅Shadow Properties)。