• Entity Framework 实践系列 —— 搞好关系 同事之间(多对多,manytomany)


    单相思(单向一对一)两情相悦(双向一对一) 到 生儿育女(一对多),这是人生的一项使命 —— 成家。

    人生还有另一项使命 —— 立业。它不是一个人的事情,也不是两个人的事情,它需要很多志同道合的人并肩作战。与你并肩作战的人叫作同事,同事之间的关系是双向的,你和他是同事,同时他和你也是同事,你有很多同事,你的同事也有很多同事。这就是“多对多”关系。

    再回到博客的应用场景,文章(BlogPost)与分类(Category)之间也是“多对多”有关系:

    一篇文章(BlogPost)可以属于多个分类,一个分类(Category)可以包含多篇文章。

    类图:

    BlogPost类的定义:

    public class BlogPost
    {
    public int ID { get; set; }
    public string Title { get; set; }
    public int BlogID { get; set; }
    public virtual BlogSite BlogSite { get; set; }
    public virtual ICollection<Category> Categories { get; set; }
    }

    Category类的定义:

    public class Category
    {
    public int ID { get; set; }
    public string Title { get; set; }
    public virtual ICollection<BlogPost> BlogPosts { get; set; }
    }

    数据库表结构及关系:

    BlogPost_Category是外键表,用于存储BlogPost与Category的多对多关系。

    那我们如何在Entity Framework中定义这种关系呢?请看代码:

    modelBuilder.Entity<BlogPost>()
    .HasMany(b
    => b.Categories)
    .WithMany(c
    => c.BlogPosts)
    .Map
    (
    m
    =>
    {
    m.MapLeftKey(
    "BlogPostID");
    m.MapRightKey(
    "CategoryID");
    m.ToTable(
    "BlogPost_Category");
    }
    );

    HasMany表示一篇文章关联多个分类,WithMany表示这些分类也分别关联着多篇文章。你有很多同事,你的同事也有很多同事。

    ToTable("BlogPost_Category")表示在BlogPost_Category表中找关系。

    MapLeftKey("BlogPostID")与MapRightKey("CategoryID")表示BlogPost要通过BlogPostID找到与自己有关系的人的CategoryID,然后再通过这个CategoryID找到这个人。Category与之相反。

    应用场景测试

    场景一:获取一篇文章,并同时得到它所属的分类

    LINQ查询:

    public BlogPost GetBlogPost(int blogPostId)
    {
    return _blogPostRepository.Entities
    .Include(p
    => p.Categories)
    .FirstOrDefault(p
    => p.ID == blogPostId);
    }

    测试代码:

    [TestMethod]
    public void GetBlogPost_Test()
    {
    var p
    = _aggBlogSiteService.GetBlogPost(1);
    Assert.IsNotNull(p);
    Console.WriteLine(
    "BlogPost:" + p.Title);
    Console.WriteLine(
    "Categories:");
    p.Categories.ToList().ForEach
    (
    c
    => Console.WriteLine("Category:" + c.Title)
    );
    }

    测试结果:

    实际执行的SQL:

    场景二:获取一个分类,并得到它所包含的文章

    LINQ查询:

    public Category GetCategory(int categoryId)
    {
    return _categoryRepository.Entities
    .Include(c
    => c.BlogPosts)
    .FirstOrDefault(c
    => c.ID == categoryId);
    }

    测试代码:

    [TestMethod]
    public void GetCategory_Test()
    {
    var category
    = _aggBlogSiteService.GetCategory(1);
    Assert.IsNotNull(category);
    Console.WriteLine(
    "Category:" + category.Title);
    Console.WriteLine(
    "BlogPosts:");
    category.BlogPosts.ToList().ForEach
    (
    p
    => Console.WriteLine("BlogPost:" + p.Title)
    );
    }

    测试结果:

    实际执行的SQL:

    测试通过!

    多对多关系看起来复杂,但只要处理好了,一点也不复杂。

    就像同事关系,虽然人越来越多,但只要目标一致,齐心协力,相处起来就很简单。

  • 相关阅读:
    关于SpringBoot的外部化配置使用记录
    深入理解Mybatis插件
    MySQL JDBC Driver 8.0+设置服务器时区
    重新认识Java注解
    深入理解Java枚举
    Spring cloud系列教程第十篇- Spring cloud整合Eureka总结篇
    Spring Cloud系列教程第九篇-Eureka自我保护机制
    安装vsftp服务器的时候遇到的问题
    spring cloud系列教程第八篇-修改服务名称及获取注册中心注册者的信息
    idea 启动命令行的时候提示不能创建PTY
  • 原文地址:https://www.cnblogs.com/dudu/p/entity_framework_many_to_many.html
Copyright © 2020-2023  润新知