Entity Framework 实践系列 —— 搞好关系 - 生儿育女(一对多,one-to-many)
2013-01-22 10:41
489 查看
从单相思(单向一对一),到两情相悦(双向一对一)并步入婚姻殿堂,接下来就是生儿育女,男人升级为父亲,如果生了很多孩子,那父亲与孩子之间的关系就是“一对多”。
一个父亲有多个孩子,一个孩子只属于一个父亲。
我们还是以博客为例,场景如下:
一个博客(BlogSite)有多篇文章(BlogPost),一篇文章只属于一个博客。
看类图:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201908/31/a90eeedf45dbceed016f446b60afa7fd.png)
看表结构:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201908/31/f6b4d1cb099f7bc008e015a0fd341e6a.png)
BlogSite与BlogPost的定义代码:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201603/69c5a8ac3fa60e0848d784a6dd461da6.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201603/69c5a8ac3fa60e0848d784a6dd461da6.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201603/69c5a8ac3fa60e0848d784a6dd461da6.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201603/69c5a8ac3fa60e0848d784a6dd461da6.gif)
下面是关键一步,在Entity Framework的OnModelCreating中通过Fluent API定义“一对多”关系:
代码简单直观,一个博客HasMany文章,一篇文章Require一个博客。
下面我们通过三个查询场景验证一下。
第一个场景:进入一个博客(BlogSite),并阅读博客中的所有文章(BlogPost)。
LINQ查询代码:
测试代码:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201603/69c5a8ac3fa60e0848d784a6dd461da6.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201603/69c5a8ac3fa60e0848d784a6dd461da6.gif)
测试结果:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201908/31/e173fc6c8227ad2325ff9526fd3267e4.png)
实际执行的SQL:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201908/31/1a199769a88984add0aaeb5111352fd7.png)
这段SQL看似复杂,实际上SQL Server会在执行时进行优化,看执行计划就知道了。
测试符合要求,通过!
第二个场景:阅读一篇文章(BlogPost),并要知道来自哪个博客(BlogSite)
LINQ查询代码:
测试代码:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201603/69c5a8ac3fa60e0848d784a6dd461da6.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201603/69c5a8ac3fa60e0848d784a6dd461da6.gif)
测试结果:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201908/31/4b39d148bed3b27333a5c6195ae24615.png)
实际执行的SQL:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201908/31/b7734c4a59bc4b71ba448551eb9e32f5.png)
测试通过!
第三个场景:看很多文章(BlogPost),并要知道每篇文章分别来自哪个博客(BlogSite)
LINQ查询代码:
测试代码:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201603/69c5a8ac3fa60e0848d784a6dd461da6.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201603/69c5a8ac3fa60e0848d784a6dd461da6.gif)
测试结果:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201908/31/03ec2f7dd9598ff0a5eeb10733fcfc7c.png)
实际执行的SQL:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201908/31/2d8c7b3a104d7569f8f6b4b00593f17c.png)
轻松过关!
小结
HasMany + WithRequired,“一对多”关系容易理解,实现简单,走的弯路也最少。
只要两情相悦了,一切都变得简单,而最难的就是如何从“单相思”到“两情相悦”。
一个父亲有多个孩子,一个孩子只属于一个父亲。
我们还是以博客为例,场景如下:
一个博客(BlogSite)有多篇文章(BlogPost),一篇文章只属于一个博客。
看类图:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201908/31/a90eeedf45dbceed016f446b60afa7fd.png)
看表结构:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201908/31/f6b4d1cb099f7bc008e015a0fd341e6a.png)
BlogSite与BlogPost的定义代码:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201603/69c5a8ac3fa60e0848d784a6dd461da6.gif)
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; } }
![](https://oscdn.geek-share.com/Uploads/Images/Content/201603/69c5a8ac3fa60e0848d784a6dd461da6.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201603/69c5a8ac3fa60e0848d784a6dd461da6.gif)
public class BlogPost { public int ID { get; set; } public string Title { get; set; } public int BlogID { get; set; } public BlogSite BlogSite { get; set; } }
![](https://oscdn.geek-share.com/Uploads/Images/Content/201603/69c5a8ac3fa60e0848d784a6dd461da6.gif)
下面是关键一步,在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); }
测试代码:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201603/69c5a8ac3fa60e0848d784a6dd461da6.gif)
[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) ); }
![](https://oscdn.geek-share.com/Uploads/Images/Content/201603/69c5a8ac3fa60e0848d784a6dd461da6.gif)
测试结果:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201908/31/e173fc6c8227ad2325ff9526fd3267e4.png)
实际执行的SQL:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201908/31/1a199769a88984add0aaeb5111352fd7.png)
这段SQL看似复杂,实际上SQL Server会在执行时进行优化,看执行计划就知道了。
测试符合要求,通过!
第二个场景:阅读一篇文章(BlogPost),并要知道来自哪个博客(BlogSite)
LINQ查询代码:
public BlogPost GetBlogPost(int blogPostId) { return _blogPostRepository.Entities .Include(p => p.BlogSite) .FirstOrDefault(p => p.ID == blogPostId); }
测试代码:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201603/69c5a8ac3fa60e0848d784a6dd461da6.gif)
[TestMethod] public void GetBlogPost_Test() { var p = _aggBlogSiteService.GetBlogPost(1); Assert.IsNotNull(p); Console.WriteLine("BlogPost Title:" + p.Title + ", " + "BlogApp:" + p.BlogSite.BlogApp); }
![](https://oscdn.geek-share.com/Uploads/Images/Content/201603/69c5a8ac3fa60e0848d784a6dd461da6.gif)
测试结果:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201908/31/4b39d148bed3b27333a5c6195ae24615.png)
实际执行的SQL:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201908/31/b7734c4a59bc4b71ba448551eb9e32f5.png)
测试通过!
第三个场景:看很多文章(BlogPost),并要知道每篇文章分别来自哪个博客(BlogSite)
LINQ查询代码:
public IEnumerable<BlogPost> GetAllBlogPosts() { return _blogPostRepository.Entities .Include(p => p.BlogSite); }
测试代码:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201603/69c5a8ac3fa60e0848d784a6dd461da6.gif)
[TestMethod] public void GetBlogPosts_Test() { _aggBlogSiteService.GetAllBlogPosts().ToList() .ForEach( p => Console.WriteLine("BlogPost Title:" + p.Title + ", " + "BlogApp:" + p.BlogSite.BlogApp) ); }
![](https://oscdn.geek-share.com/Uploads/Images/Content/201603/69c5a8ac3fa60e0848d784a6dd461da6.gif)
测试结果:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201908/31/03ec2f7dd9598ff0a5eeb10733fcfc7c.png)
实际执行的SQL:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201908/31/2d8c7b3a104d7569f8f6b4b00593f17c.png)
轻松过关!
小结
HasMany + WithRequired,“一对多”关系容易理解,实现简单,走的弯路也最少。
只要两情相悦了,一切都变得简单,而最难的就是如何从“单相思”到“两情相悦”。
相关文章推荐
- Entity Framework 实践系列 —— 搞好关系 - 生儿育女(一对多,one-to-many)
- Entity Framework 实践系列 —— 搞好关系 - 生儿育女(一对多,one-to-many)
- Entity Framework 实践系列 —— 搞好关系 - 单相思(单向一对一,one-to-one)
- Entity Framework 实践系列 —— 搞好关系 - 单相思(单向一对一,one-to-one)
- Entity Framework 实践系列 —— 搞好关系 - 两情相悦(双向一对一,one-to-one)- 续
- Entity Framework 实践系列 —— 搞好关系 - 同事之间(多对多,many-to-many)
- Entity Framework 实践系列 —— 搞好关系 - 同事之间(多对多,many-to-many)
- Entity Framework 实践系列 —— 搞好关系 - 单相思(单向一对一,one-to-one)【转】
- Entity Framework 实践系列 —— 搞好关系 - 两情相悦(双向一对一,one-to-one)- 续
- Entity Framework 实践系列 —— 搞好关系 - 单相思(单向一对一,one-to-one)
- Entity Framework 实践系列 —— 搞好关系 - 同事之间(多对多,many-to-many)
- Entity Framework 实践系列 —— 搞好关系 - 两情相悦(双向一对一,one-to-one)- 续
- Entity Framework 实践系列 —— 搞好关系 - 单相思(单向一对一,one-to-one)
- JPA关系映射系列三:one-to-many和many-to-one
- JPA关系映射系列三:one-to-many和many-to-one
- JPA关系映射系列三:one-to-many和many-to-one
- hibernate 3.5 一对多单项关联(OneToMany)
- hibernate映射技巧one-to-many(双向一对多)
- Mybatis 一对多(OneToOne)关系映射
- oracle和hibernate的一对一(OneToOne),一对多(OneToMany),(详细图解)