Entity Framework Core 简明教程(3)- 关系处理

在数据库层面,表之间关系,通过主键、外键来实现,基于约束 (constraint) 和数据完整性来制约。 在 EF Core 技术层面,并不是简单地与数据库这些关系和约束对应,EF Core 有它自己的机制。本篇介绍 EF core 在处理表关系方面的典型技术点。为了理解的方便,示例数据库只包含两个表:Articles (文章)和 Comments (文章评论)。很明显,Articles 和 Comments 是一对多关系(一篇文章存在多条评论论)。在数据库中,Comments 表的 Id 字段是外键,指向 Articles 表的 主键 Id 字段。一对多关系是数据表最重要的关系。

数据库中的关系

请添加图片描述

请添加图片描述

对象模型中的关系

在 EF Core 中,我们在实体类中定义模型的关系,一般通过导航属性来实现。比如刚才的表模型,在 Articles 实体中, Comments 属性是一个 List,表达 Article 含有多条 Comment。

请添加图片描述
当然,这只是 EF Core 提供的的一种实现方式,也可以在 Comments 实体中定义导航属性,指向 Articles 实体。在两个类中同时定义也是可以的。

请添加图片描述

注意,这里并不需要显示定义 ArticleId 字段来标识 Comments 表的外键。

EF Core 关系映射

EF Core 中关系映射,最基本的内容包括:

  • 为每一个实体 (entity) 添加主键
  • 为实体添加外键 (如果有的话)
  • 通过主键外键定义两个实体的参照关系 (能够清晰地体现出一对多)

请添加图片描述
(示例为在多的一方定义)

关系表的增删改查

刚才的示例中,在 Articles 实体中和 Comments 实体中,都定义了导航属性。这样我们可以很方便的进行 Create 操作。示例方式一:利用 Articles 实体的导航属性:

[TestMethod]
public void TestInsert1()
{
    var a1 = new Article 
    { 
        Title = ".net下主要ORM框架",
        Content = "xxxxx"
    };

    a1.Comments.Add(new Comment { CommentContent = "非常赞"});
    a1.Comments.Add(new Comment { CommentContent = "强烈支持"});

    using var context = new AppDbContext();
    context.Articles.Add(a1);
    context.SaveChanges();
}

注意到:不需要显式为 Comment 实体的 Article 属性赋值

示例新增方式二:利用 Comment 实体的导航属性:

[TestMethod]
public void TestInsert2()
{
    var a1 = new Article
    {
        Title = "EFCore 从入门到精通",
        Content = "EFCore"
    };

    var c1 = new Comment { 
        CommentContent = "这篇文章真不错",
        Article = a1
    };

    var c2 = new Comment
    {
        CommentContent = "这篇文章写的不错呀",
        Article = a1
    };

    a1.Comments.Add(c1);
    a1.Comments.Add(c2);

    using var context = new AppDbContext();
    context.Articles.Add(a1);
    context.SaveChanges();
}

假设我们想对已有的 Article 进行新增操作,我们也能利用导航属性来实现,举例如下:

[TestMethod]
public void TestAddComments()
{
    using var context = new AppDbContext();

    var article = context.Articles.Single(a => a.Id == 20);
    article.Comments.Add(new Comment {CommentContent = "我觉得文章不怎么样" });

    context.SaveChanges();
}

查询中获取表关系

刚才我们看到,Article 表和 Comment 表已经定义了主键和外键,在模型层面,定义了导航属性,并且定义了关系。此时我们试着查询出 Id == 20 的文章以及文章相应的 comment,我们先尝试下面的代码:

[TestMethod]
public void TestQueryArticles()
{
    using var context = new AppDbContext();

    var article = context.Articles.Single(a=>a.Id==20);
    Console.WriteLine(article.ToString());
    article.Comments.ForEach(Console.WriteLine);
}

我们发现,并没有关联到 comments 实体:

请添加图片描述

如果在查询的时候,需要关联数据,需要利用 Microsoft.EntityFrameworkCore 的扩展方法 Include() 方法:

[TestMethod]
public void TestQueryArticleAndComments()
{
    using var context = new AppDbContext();
    var article = context.Articles.Include(a=>a.Comments).Single(a=>a.Id==20);

    // print article and related comments
    Console.WriteLine(article.ToString());
    article.Comments.ForEach(Console.WriteLine);
}

运行的测试结果如下,能够获取到 article 的 comments:

请添加图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值