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

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

数据库中的关系

Entity Framework Core 简明教程(3)- 关系处理_第1张图片

Entity Framework Core 简明教程(3)- 关系处理_第2张图片

对象模型中的关系

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

Entity Framework Core 简明教程(3)- 关系处理_第3张图片
当然,这只是 EF Core 提供的的一种实现方式,也可以在 Comments 实体中定义导航属性,指向 Articles 实体。在两个类中同时定义也是可以的。

Entity Framework Core 简明教程(3)- 关系处理_第4张图片

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

EF Core 关系映射

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

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

Entity Framework Core 简明教程(3)- 关系处理_第5张图片
(示例为在多的一方定义)

关系表的增删改查

刚才的示例中,在 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 实体:

Entity Framework Core 简明教程(3)- 关系处理_第6张图片

如果在查询的时候,需要关联数据,需要利用 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:

Entity Framework Core 简明教程(3)- 关系处理_第7张图片

你可能感兴趣的:(Microsoft,.Net,数据库,sql,java)