Entity Framework 实践系列 —— 搞好关系 - 生儿育女(一对多,one-to-many)

本文深入探讨了数据库与关系型模型的建立过程,从单向一对一的关系(单相思)出发,最终达到双向一对一的关系(两情相悦),并实现这一过程在代码中的应用。通过使用Entity Framework,展示了如何通过Fluent API定义'一对多'关系,并提供了三个关键查询场景的示例,确保读者能够理解和实现在实际项目中的应用。

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

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

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

一个博客(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,“一对多”关系容易理解,实现简单,走的弯路也最少。

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

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值