Entity Framework 实践系列 —— 搞好关系 - 同事之间(多对多,many-to-many)

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

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

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

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

类图:

2011070917092622.png

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 ; }
}

数据库表结构及关系:

2011070917261970.png

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)
);
}

测试结果:

2011070918035868.png

实际执行的SQL:

2011070917570017.png

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

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)
);
}

测试结果:

2011070918002663.png

实际执行的SQL:

2011070918022455.png

测试通过!

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值