zoukankan      html  css  js  c++  java
  • Entity Framework 实践系列 —— 搞好关系 生儿育女(一对多,onetomany)

    单相思(单向一对一),到两情相悦(双向一对一)并步入婚姻殿堂,接下来就是生儿育女,男人升级为父亲,如果生了很多孩子,那父亲与孩子之间的关系就是“一对多”。

    一个父亲有多个孩子,一个孩子只属于一个父亲。

    我们还是以博客为例,场景如下:

    一个博客(BlogSite)有多篇文章(BlogPost),一篇文章只属于一个博客。

    看类图:

    看表结构:

    BlogSite与BlogPost的定义代码:

    public class BlogSite
    {
    public int BlogID { get; set; }
    public string BlogApp { get; set; }
    public bool IsActive { get; set; }
    public Guid UserID { get; set; }
    public virtual BlogUser BlogUser { get; set; }
    public virtual ICollection<BlogPost> BlogPosts { get; set; }
    }

    public class BlogPost
    {
    public int ID { get; set; }
    public string Title { get; set; }
    public int BlogID { get; set; }
    public BlogSite BlogSite { get; set; }
    }

    下面是关键一步,在Entity Framework的OnModelCreating中通过Fluent API定义“一对多”关系:

    modelBuilder.Entity<BlogSite>()
    .HasMany(b
    => b.BlogPosts)
    .WithRequired(p
    => p.BlogSite);

    代码简单直观,一个博客HasMany文章,一篇文章Require一个博客。

    下面我们通过三个查询场景验证一下。

    第一个场景:进入一个博客(BlogSite),并阅读博客中的所有文章(BlogPost)。

    LINQ查询代码:

    public BlogSite GetBlogSite(int blogId)
    {
    return _blogSiteReposiotry.Entities
    .Include(b
    => b.BlogPosts)
    .FirstOrDefault(b
    => b.BlogID == blogId);
    }

    测试代码:

    [TestMethod]
    public void GetBlogSite_Test()
    {
    var blogSite
    = _aggBlogSiteService.GetBlogSite(1);
    Assert.IsNotNull(blogSite);
    Console.WriteLine(
    "BlogApp:" + blogSite.BlogApp);
    Console.WriteLine(
    "BlogPosts:");
    blogSite.BlogPosts.ToList().ForEach
    (
    p
    => Console.WriteLine(p.Title + "-" + p.BlogSite.BlogApp)
    );
    }

    测试结果:

    实际执行的SQL:

    这段SQL看似复杂,实际上SQL Server会在执行时进行优化,看执行计划就知道了。

    测试符合要求,通过!

    第二个场景:阅读一篇文章(BlogPost),并要知道来自哪个博客(BlogSite)

    LINQ查询代码:

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

    测试代码:

    [TestMethod]
    public void GetBlogPost_Test()
    {
    var p
    = _aggBlogSiteService.GetBlogPost(1);
    Assert.IsNotNull(p);
    Console.WriteLine(
    "BlogPost Title:" + p.Title + ", " +
    "BlogApp:" + p.BlogSite.BlogApp);
    }

    测试结果:

    实际执行的SQL:

    测试通过!

    第三个场景:看很多文章(BlogPost),并要知道每篇文章分别来自哪个博客(BlogSite)

    LINQ查询代码:

    public IEnumerable<BlogPost> GetAllBlogPosts()
    {
    return _blogPostRepository.Entities
    .Include(p
    => p.BlogSite);
    }

    测试代码:

    [TestMethod]
    public void GetBlogPosts_Test()
    {
    _aggBlogSiteService.GetAllBlogPosts().ToList()
    .ForEach(
    p
    => Console.WriteLine("BlogPost Title:" + p.Title + ", " +
    "BlogApp:" + p.BlogSite.BlogApp)
    );
    }

    测试结果:

    实际执行的SQL:

    轻松过关!

    小结

    HasMany + WithRequired,“一对多”关系容易理解,实现简单,走的弯路也最少。

    只要两情相悦了,一切都变得简单,而最难的就是如何从“单相思”到“两情相悦”。

    HasMany
    
  • 相关阅读:
    Java实现 LeetCode 402 移掉K位数字
    Java实现 LeetCode 402 移掉K位数字
    Java实现 LeetCode 401 二进制手表
    Java实现 LeetCode 401 二进制手表
    wpa_supplicant使用笔记-wpa_cli iwconfig
    Linux下的定时器:alarm()与setitimer()
    在 Windows 下远程桌面连接 Linux
    assert()函数用法总结
    linux下svn修改用户名和密码
    VirtualBox
  • 原文地址:https://www.cnblogs.com/dudu/p/entity_framework_one_to_many.html
Copyright © 2011-2022 走看看