EntityFrameWork Code First 一对多关系处理
场景1: 一个文章类别(Category)下含有多篇文章(Article),而某篇文章只能对应一个类别
Article和Category的代码如下:
/// <summary> /// 文章信息 /// </summary> public class Article:ModelBase { //标题 public string Title { get; set; } //内容 public string Content { get; set; } //类别 public Category Category { get; set; } }
public class Category:ModelBase { //类别名字 public string Name { get; set; } //某类别下含很多文章 public ICollection<Article> Articles { get; set; } }
下面是关键一步,在Entity Framework的OnModelCreating中通过Fluent API定义“一对多”关系:
表示站在Category的角度HasMany含有多篇Articles,WithRequired表明Articles必须包含文章类别
public class CmsDbContext : DbContextBase { public CmsDbContext():base(CachedConfigContext.Current.DaoConfig.Cms,new LogDbContext()) { } protected override void OnModelCreating(DbModelBuilder modelBuilder) { // Database.SetInitializer<CmsDbContext>(null); //定义一对多的关系 modelBuilder.Entity<Category>().HasMany(c => c.Articles) .WithRequired(a => a.Category); base.OnModelCreating(modelBuilder); } public DbSet<Article> Articles { get; set; } public DbSet<Category> Categorys { get; set; } }
分别编写两个场景来测试以下结果:
public interface ICmsService { //Article GetArticle(int id); Category GetCategory(); Article GetArticle(); }
使用LINQ to SQL 来查询Category和Articles
Include(),两表必须含有外键关系,只需要指定键名对应的类属性名即可,不需指定结果字段(即全部映射)。默认搜索某表时,不会顺带查询外键表,直到真正使用时才会再读取数据库查询;若是使用 Include(),则会在读取本表时把指定的外键表信息也读出来。
public Category GetCategory() { using (var session = new CmsDbContext()) { return session.Categorys.Include("Articles").FirstOrDefault(); } } public Article GetArticle() { using (var session = new CmsDbContext()) { return session.Articles.Include("Category").FirstOrDefault(); } }
这里使用ASP.NET MVC来显示结果:
在View中传入的model可以在视图的Model对象直接获取数据(需要在视图页指定类型),ViewData数据也可以在视图页可以获得(需要强制转换)
public class CategoryController : AdminControllerBase { // // GET: /Cms/Category/ public ActionResult Index() { var model = this.CmsService.GetCategory(); ViewData["Acticle"] = this.CmsService.GetArticle(); return View(model); } }
视图页:
@using Qxun.Framework.Contract @using Qxun.Framework.Web.Controls @using Qxun.Cms.Contract @using Qxun.Web @{ var secondPosition = ViewData["Acticle"] as Qxun.Cms.Contract.Article; } @model Qxun.Cms.Contract.Category <h2>第一个场景加载Category过程中加载所有的Article</h2> @if(@Model!=null){ if (Model.Articles != null) { foreach(var item in Model.Articles) { @item.ID<br/> @item.Title<br/> @item.Content<br/> } } } <h2>第二个场景加载Article得到Article是哪个Category</h2> 文章类别:@secondPosition.Category.Name
显示结果: