博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Entity Framework DbSet<T>之Include方法与IQueryable<T>扩展方法Include的使用
阅读量:4611 次
发布时间:2019-06-09

本文共 4494 字,大约阅读时间需要 14 分钟。

Entity Framework使用Code First方式时,实体之间已经配置好关系,根据实际情况某些情况下需要同时获取导航属性,比如获取商品的同时需要获取分类属性(导航属性),或者基于优化方面考虑等,下面来看一个例子

例子中有会员实体类(Member)与角色实体类(Role),Role与Member的关系是1:n,控制台应用程序代码如下:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Data.Entity;namespace ConsoleApplication2{    class Program    {        static void Main(string[] args)        {            EFContext
efMemberContext = new EFContext
(); var members = efMemberContext.Set
().ToList(); foreach (Member item in members) { Console.WriteLine(item.Role.Name); } Console.ReadKey(); } }}
EFContext类、Member类、Role类以及Mapping类如下:
using System;using System.Collections.Generic;using System.Data.Entity;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Linq.Expressions;namespace ConsoleApplication2{    public partial class EFContext
: DbContext where T : class { public EFContext(): base("name=MyConnectionString") { } protected override void OnModelCreating(DbModelBuilder modelBuilder) { Database.SetInitializer
> (null); modelBuilder.Configurations.Add(new MemberMap()); modelBuilder.Configurations.Add(new RoleMap()); base.OnModelCreating(modelBuilder); } public DbSet
Table { get; set; } public IQueryable
GetList(Expression
> where) { return this.Table.Where(where); } }}
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace ConsoleApplication2{    public partial class Member    {        public int Id { get; set; }        public string Name { get; set; }        public string Password { get; set; }        public bool Delete{ get; set; }        public int RoleId { get; set; }        public virtual Role Role { get; set; }    }}
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 MemberMap : EntityTypeConfiguration
{ public MemberMap() { this.ToTable("Member"); this.HasKey(m => m.Id); this.HasRequired(m => m.Role).WithMany(r => r.Members).HasForeignKey(m => m.RoleId); } }}
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace ConsoleApplication2{    public partial class Role    {        public int Id { get; set; }        public string Name { get; set; }        public virtual ICollection
Members { get; set; } }}
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
{ 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
().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
efMemberContext = new EFContext
();var members = efMemberContext.Set
().Where(m =>m.RoleId < 5).Include("Role").ToList();foreach (Member item in members){ Console.WriteLine("{0}:{1}",item.Name,item.Role.Name);}Console.ReadKey();

 

 运行程序,如下:

 

 

转载于:https://www.cnblogs.com/sjqq/p/7523619.html

你可能感兴趣的文章
高斯 到 正态分布 的前世今生
查看>>
for 循环遍历字典中的键值两种方法
查看>>
计算客 商品推荐走马灯(简单)(求区间全部连续的回文串价值)
查看>>
IOS &#39;NSInternalInconsistencyException&#39;
查看>>
vim安装ctags,taglist和Pydiction
查看>>
机器学习系列之EM算法
查看>>
Time.timeScale 对 协程WaitForSeconds的影响
查看>>
Java并发编程-CAS
查看>>
SQL Server 2008的备份和日志收缩
查看>>
sqlserver数据库数据字典生成器
查看>>
iOS经典面试题 (一)
查看>>
Linux : 从私钥中提取公钥
查看>>
Quartz.Net分布式任务管理平台
查看>>
android 应用分发
查看>>
58同城2018提前批前端笔试题总结
查看>>
compilation与编译
查看>>
useradd mfs -s /sbin/nologin -M
查看>>
mysql数据库:数据类型、存储引擎、约束、
查看>>
LeetCode-Find the Celebrity
查看>>
LeetCode-Longest Increasing Subsequence
查看>>