Entity Framework DbSet<T>之Include方法与IQueryable<T>扩展方法Include的使用
2017-09-14 22:36
633 查看
Entity Framework使用Code First方式时,实体之间已经配置好关系,根据实际情况某些情况下需要同时获取导航属性,比如获取商品的同时需要获取分类属性(导航属性),或者基于优化方面考虑等,下面来看一个例子
例子中有会员实体类(Member)与角色实体类(Role),Role与Member的关系是1:n,控制台应用程序代码如下:
数据库中现有数据如下:
运行程序 ,在SQL Profiler中看到生成了如下的语句:
1. 执行efMemberContext.DbSet<Member>().ToList();生成的SQL:
2. foreach循环了五次,每次生成一条SQL,如下:
这里省略描述了其中三条SQL,SQL语句类似,只是读取Role属性时根据不同的RoleId获取信息,所以只是参数值 不同
从上面的例子可以看出循环几次为了获取导航属性而生成了几条SQL,如果数据库里表有数据量很大,这样的方式对性能的影响可想而知。 根据上面的例子,现在想有没有一种方法在获取Member的同时获取Role信息,也就是生成的SQL是两个表inner join ,于是Include就发挥了作用了。改写Main()方法中的代码如下:
上面是获取Member时同时获取导航属性Role信息,这样在生成SQL里就是inner join ,再次运行程序,这里可以看到,在SQL Profiler中只执行了一次SQL,而SQL是带inner join的形式
上面两种方式的控制台输出如下:
这里可能有人会有疑问了,如里EF通用类封装了没有公开DbSet<T>类型的属性或者只有IQueryable<T>类型的返回,又或者DbSet<T>().Where(e => true)之后再想Include怎么办?
如果是使用Entity Framework,System.Data.Entity.QueryableExtensions类封装了IIQueryable<T>的扩展方法,其中有Include扩展方法,引用命名空间System.Data.Entity可以使用。
下面是获取RoleId<5的会员信息与对应的角色信息:
运行程序,如下:
例子中有会员实体类(Member)与角色实体类(Role),Role与Member的关系是1:n,控制台应用程序代码如下:
using System; using System.Collections.Generic; using System.Data.Entity.ModelConfiguration; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication2 { public class RoleMap: EntityTypeConfiguration<Role> { public RoleMap() { this.ToTable("Role"); this.HasKey(r => r.Id); } } }
数据库中现有数据如下:
运行程序 ,在SQL Profiler中看到生成了如下的语句:
1. 执行efMemberContext.DbSet<Member>().ToList();生成的SQL:
2. foreach循环了五次,每次生成一条SQL,如下:
这里省略描述了其中三条SQL,SQL语句类似,只是读取Role属性时根据不同的RoleId获取信息,所以只是参数值 不同
从上面的例子可以看出循环几次为了获取导航属性而生成了几条SQL,如果数据库里表有数据量很大,这样的方式对性能的影响可想而知。 根据上面的例子,现在想有没有一种方法在获取Member的同时获取Role信息,也就是生成的SQL是两个表inner join ,于是Include就发挥了作用了。改写Main()方法中的代码如下:
var members = efMemberContext.Set<Member>().Include("Role").ToList();
上面是获取Member时同时获取导航属性Role信息,这样在生成SQL里就是inner join ,再次运行程序,这里可以看到,在SQL Profiler中只执行了一次SQL,而SQL是带inner join的形式
上面两种方式的控制台输出如下:
这里可能有人会有疑问了,如里EF通用类封装了没有公开DbSet<T>类型的属性或者只有IQueryable<T>类型的返回,又或者DbSet<T>().Where(e => true)之后再想Include怎么办?
如果是使用Entity Framework,System.Data.Entity.QueryableExtensions类封装了IIQueryable<T>的扩展方法,其中有Include扩展方法,引用命名空间System.Data.Entity可以使用。
下面是获取RoleId<5的会员信息与对应的角色信息:
EFContext<Member> efMemberContext = new EFContext<Member>(); var members = efMemberContext.Set<Member>().Where(m =>m.RoleId < 5).Include("Role").ToList(); foreach (Member item in members) { Console.WriteLine("{0}:{1}",item.Name,item.Role.Name); } Console.ReadKey();
运行程序,如下:
相关文章推荐
- Entity Framework DbSet<T>之Include方法与IQueryable<T>扩展方法Include的使用
- MVC分页控件之二,为IQueryable定义一个扩展方法,直接反回PagedList<T>结果集(转)
- 【转载】MVC分页控件之二,为IQueryable定义一个扩展方法,直接反回PagedList<T>结果集
- IEnumerable<T>与IQueryable<T>以及.net的扩展方法
- MVC分页控件之二,为IQueryable定义一个扩展方法,直接反回PagedList<T>结果集
- 解决 ”不允许在查询中显式构造实体类型“问题及使用其他方法实现返回 List<Model对象>或者IQueryable<Model对象>对象
- 写一个针对IQueryable<T>的扩展方法支持动态排序
- VS2010使用扩展方法对List<T>进行随机排序
- 讲解.NET 集合中使用Count属性和扩展方法Count<T>()区别
- Entity Framework中使用IEnumerable<T>、IQueryable<T>及IList<T>的区别
- 扩展方法IEnumerable<T>转换为IList<SelectListItem> ,提供@Html.DropDownList使用
- 在VS中使用#include <bits/stdc++.h>的方法
- 复习扩展方法 涉及委托,这里我使用自定义委托类型 public delegate bb MyFunc<in T,out bb> (T arg)
- 在VS中使用#include <bits/stdc++.h>的方法
- JSP 中使用<%@include%> 报 Duplicate local variable path 错误的解决方法
- Entity Framework中使用IEnumerable<T>、IQueryable<T>及IList<T>的区别
- 使用<jsp:include>,不想写死URL,动态生成URL的解决的方法
- Entity Framework API介绍 -- DbSet<>().Find()
- Queryable.GroupBy<TSource, TKey> 方法 (IQueryable<TSource>, Expression<Func<TSource, TKey>>) 转
- asp.net mvc 2 简简单单做开发 使用DataContext扩展方法Find<TEntity>(TEntity obj) 遇到的问题