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<Member> efMemberContext = new EFContext<Member>();
var members = efMemberContext.Set<Member>().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<T> : DbContext where T : class
{
public EFContext(): base("name=MyConnectionString")
{
} protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
Database.SetInitializer<EFContext<T>> (null);
modelBuilder.Configurations.Add(new MemberMap());
modelBuilder.Configurations.Add(new RoleMap());
base.OnModelCreating(modelBuilder);
} public DbSet<T> Table { get; set; } public IQueryable<T> GetList(Expression<Func<T,bool>> 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<Member>
{
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<Member> 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<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 < ).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的使用的更多相关文章

  1. C#扫盲之:带你掌握C#的扩展方法、以及探讨扩展方法的本质、注意事项

    1.为什么需要扩展方法 .NET3.5给我们提供了扩展方法的概念,它的功能是在不修改要添加类型的原有结构时,允许你为类或结构添加新方法. 思考:那么究竟为什么需要扩展方法呢,为什么不直接修改原有类型呢 ...

  2. 【转载】C#扫盲之:带你掌握C#的扩展方法、以及探讨扩展方法的本质、注意事项

    1.为什么需要扩展方法 .NET3.5给我们提供了扩展方法的概念,它的功能是在不修改要添加类型的原有结构时,允许你为类或结构添加新方法. 思考:那么究竟为什么需要扩展方法呢,为什么不直接修改原有类型呢 ...

  3. Entity Framework Core的坑:Skip/Take放在Select之前造成Include的实体全表查询

    今天将一个迁移至 ASP.NET Core 的项目放到一台 Linux 服务器上试运行.站点启动后,浏览器打开一个页面一直处于等待状态.接着奇怪的事情发生了,整个 Linux 服务器响应缓慢,ssh命 ...

  4. 使用jquery获取url及url参数的方法及定义JQuery扩展方法

    1.jquery获取url很简单,代码如下: window.location.href; 其实只是用到了javascript的基础的window对象,并没有用jquery的知识. 2.jquery获取 ...

  5. System.Web.Mvc.HtmlHelper<dynamic>”没有名为“Partial”的适用方法,但似乎有一个具有该名称的扩展方法。扩展方法不能进行动态调度。请考虑强制转换动态参数,或调用该扩展方法但不使用扩展方法语法。

    MVC 调用分布式图,传了没有定义的参数,,参数写得不对

  6. 浅析Entity Framework Core2.0的日志记录与动态查询条件

    前言 Entity Framework Core 2.0更新也已经有一段时间了,园子里也有不少的文章.. 本文主要是浅析一下Entity Framework Core2.0的日志记录与动态查询条件 去 ...

  7. AppBox升级进行时 - Entity Framework的增删改查

    AppBox 是基于 FineUI 的通用权限管理框架,包括用户管理.职称管理.部门管理.角色管理.角色权限管理等模块. Entity Framework新增数据 以新增用户为例,作为对比,先来看下使 ...

  8. Entity Framework Code First执行SQL语句、视图及存储过程

    1.Entity Framework Code First查询视图 Entity Framework Code First目前还没有特别针对View操作的方法,但对于可更新的视图,可以采用与Table ...

  9. 关于Entity Framework自动关联查询与自动关联更新导航属性对应的实体注意事项说明

    一.首先了解下Entity Framework 自动关联查询: Entity Framework 自动关联查询,有三种方法:Lazy Loading(延迟加载),Eager Loading(预先加载) ...

随机推荐

  1. Ubuntu下搭建tftp服务器最简单方法

    今天开始调试ARM的板子,要通过tftp下载到板子上,所以又要配置tftp服务器,真的烦死了… (本人酷爱装系统,所以经常都要搞配置) 因为之前已经在Ubuntu下搭建过很多次tftp服务器了,但是一 ...

  2. String s = new String("xyz");产生了几个对象?

    面试官Q1:请问String s = new String("xyz");产生了几个对象? 对于这个问题,老套路先上代码: public class StringTest { pu ...

  3. Atitit  验证 数字验证 非空验证的最佳算法  h5

    Atitit  验证 数字验证 非空验证的最佳算法  h5 <td><select class="searchBox-select"   style=" ...

  4. [k8s]kube-dns/dashboard排错历险记(含sa加载用法/集群搭建)

    kube-dns原理 参考: 组件架构看这个就够了 http://cizixs.com/2017/04/11/kubernetes-intro-kube-dns 设置细节看这个就够了 http://b ...

  5. [转]Object.keys()和for in的排序问题

    原文地址:https://www.jianshu.com/p/a086ff48be6e Object.keys()和for in 具有相同的排列顺序 如果属性名的类型是Number,那么Object. ...

  6. HDOJ 1393 Weird Clock(明确题意就简单了)

    Problem Description A weird clock marked from 0 to 59 has only a minute hand. It won't move until a ...

  7. 【iCore4 双核心板_ARM】例程四:USART实验——通过命令控制LED

    实验原理: 开发板上自带一片CH340芯片,完成本实验电脑需要安装CH340驱动, CH340的TXD连接STM32的GPIO(PXC7),CH340的RXD连接STM32的 GPIO(PC6),通过 ...

  8. GPT(保护分区)解决办法

    教你在硬盘被GPT保护分区后怎么格式化  GUID 分区表 (GPT) 作为可扩展固件接口 (EFI) 计划的一部分而引入.与 PC 以前通用的旧的主引导记录 (MBR) 分区方案相比,GPT 为磁盘 ...

  9. svn常见错误解决

    Svn冲突导致锁住的解决方案:错误码:svn: E155037: Previous operation has not finished; run 'cleanup' if it was interr ...

  10. elasticsearch client 为空 错误信息:java.lang.NoSuchMethodError: com.google.common.util.concurrent.MoreExecutors.directExecut‌​or()Ljava/util/concu‌​rrent/Executor

    错误信息:java.lang.NoSuchMethodError: com.google.common.util.concurrent.MoreExecutors.directExecut‌​or() ...