从性能的角度出发,能够减少 增,删,改,查,跟数据库打交道次数,肯定是对性能会有所提升的(这里单纯是数据库部分)。

今天主要怎样减少Entity Framework查询跟数据库打交道的次数,来提高查询性能。

举一个大家最常用功能 “分页” 功能。先贴一段代码。

       private static IEnumerable<OrderModel> FindPagerOrders(int pageSize, int pageIndex, out int totalCount)
{
using (var dbContext = new EntityFrameworkPlusDbContext())
{
var orders = dbContext.Orders.OrderBy(o => o.CreateDateTime); totalCount = orders.Count(); var pagerOrders = orders.Skip((pageIndex - ) * pageSize).Take(pageSize); return pagerOrders .ToList();
}
}

这类型的代码,大家估计都看到过,也自己写过,简单分析一下。

orders.Count() 返回int 类型,肯定要查询出数据库才知道订单总笔数。

pagerOrders.ToList() 返回  IEnumerable<T> 类型,这个不用解释Entity Framework  IEnumerable 和 IQueryable 区别是

IEnumerable 会执行SQL,IQueryable 而不会。所以这句也会去数据库查询一次。

那整个分页功能用Entity Framework 就是最少要两次数据库查询,刚刚上面说了,一个基本的提高性能方法就要减少与数据库打交道次数。

从“分页”功能来说,要是变成只有一次与数据库打交道,那就是对性能有大提升。Entity Framework 自身是没有提供这样的方法。

Entity Framework Plus 库 Query Future 扩展,是一个对Entity Framework 功能的延伸和扩展,能够做到减少数据库打交道次数。使查询性能更高。

 一 . Entity Framework Plus 库 Query Future 安装

1.  解决方案 还是我上一篇 第一篇 Entity Framework Plus 之 Audit 用的解决方案“EntityFrameworkPlusSolution”,新增 “EntityFrameworkPlus.QueryFuture.Demo” 控制台项目,作为Entity Framework Plus 库 Query Future 扩展 应用和展示功能项目。项目结构截图如下

项目关系图 (代码图)

2. 为了方便Demo,新增商品业务 相关的 Model,Mapping,以及改动DbContext 如下代码

GoodsModel

using System;

namespace EntityFrameworkPlus.Models
{
public class GoodsModel
{
public System.Guid GoodsGuid { get; set; }
public string GoodsNo { get; set; }
public string GoodsName { get; set; }
public string GoodsBrand { get; set; }
public decimal UnitPrice { get; set; }
public string Description { get; set; }
public string Creator { get; set; }
public System.DateTime CreateDateTime { get; set; }
public string LastModifier { get; set; }
public DateTime? LastModifiedDateTime { get; set; }
}
}

GoodsMap

using System.Data.Entity.ModelConfiguration;
using EntityFrameworkPlus.Models; namespace EntityFrameworkPlus.Mappings
{
public class GoodsMap: EntityTypeConfiguration<GoodsModel>
{
public GoodsMap()
{
// Primary Key
this.HasKey(t => t.GoodsGuid); // Properties
this.Property(t => t.GoodsNo)
.IsRequired()
.HasMaxLength(); this.Property(t => t.GoodsName)
.IsRequired()
.HasMaxLength(); this.Property(t => t.GoodsBrand)
.IsRequired()
.HasMaxLength(); this.Property(t => t.Creator)
.IsRequired()
.HasMaxLength(); this.Property(t => t.LastModifier)
.HasMaxLength(); // Table & Column Mappings
this.ToTable("Sample_Goods");
this.Property(t => t.GoodsGuid).HasColumnName("GoodsGuid");
this.Property(t => t.GoodsNo).HasColumnName("GoodsNo");
this.Property(t => t.GoodsName).HasColumnName("GoodsName");
this.Property(t => t.GoodsBrand).HasColumnName("GoodsBrand");
this.Property(t => t.UnitPrice).HasColumnName("UnitPrice");
this.Property(t => t.Description).HasColumnName("Description");
this.Property(t => t.Creator).HasColumnName("Creator");
this.Property(t => t.CreateDateTime).HasColumnName("CreateDateTime");
this.Property(t => t.LastModifier).HasColumnName("LastModifier");
this.Property(t => t.LastModifiedDateTime).HasColumnName("LastModifiedDateTime");
}
}
}

EntityFrameworkPlusDbContext

using System.Data.Entity;
using EntityFrameworkPlus.Mappings;
using EntityFrameworkPlus.Models;
using Z.EntityFramework.Plus; namespace EntityFrameworkPlus.DbContext
{
public class EntityFrameworkPlusDbContext : System.Data.Entity.DbContext
{
public EntityFrameworkPlusDbContext()
: base("EntityFrameworkPlusConnection")
{
}
public DbSet<AuditEntry> AuditEntries { get; set; }
public DbSet<AuditEntryProperty> AuditEntryProperties { get; set; }
public DbSet<OrderModel> Orders { get; set; }
public DbSet<GoodsModel> Goodses { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder)
{ modelBuilder.Configurations.Add(new OrderMap());
modelBuilder.Configurations.Add(new GoodsMap()); base.OnModelCreating(modelBuilder);
} }
}

3. 右键 “EntityFrameworkPlus.QueryFuture.Demo” 项目,选择“管理NuGet程序包”,关联部分  右上角搜索“Z.EntityFramework.Plus” ,然后选择 “EntityFramework Plus (EF6) | Query Deferred”&“EntityFramework Plus (EF6) | Query Futurn” 两项安装

二. Entity Framework Plus  库 Query Future 扩展功能实作

1. 在 “EntityFrameworkPlus.QueryFuture.Demo” 项目 Program 新增3个静态方法,分别是

FindOrdersWithGoodsies()  查询订单信息和商品信息

FindPagerOrders(int pageSize, int pageIndex, out int totalCount)  订单分页查询

FindGoodsMaxWithMinUnitPrice() 查询单价最大和最小的商品

详细代码如下

using System.Collections.Generic;
using System.Linq;
using EntityFrameworkPlus.DbContext;
using EntityFrameworkPlus.Models;
using Z.EntityFramework.Plus; namespace EntityFrameworkPlus.QueryFuture.Demo
{
class Program
{
static void Main(string[] args)
{
//1.查询订单信息和商品信息
FindOrdersWithGoodsies(); //2. 订单分页查询
//var totalCount = 0;
//FindPagerOrders(10, 1, out totalCount); //3.查询单价最大和最小的商品
//FindGoodsMaxWithMinUnitPrice();
} private static void FindOrdersWithGoodsies()
{
using (var dbContext = new EntityFrameworkPlusDbContext())
{
var futureOrders = dbContext.Orders.Future();
var futureGoodsies = dbContext.Goodses.Future();
var orders = futureOrders.ToList();
var goodsies = futureGoodsies.ToList();
}
} private static IEnumerable<OrderModel> FindPagerOrders(int pageSize, int pageIndex, out int totalCount)
{
using (var dbContext = new EntityFrameworkPlusDbContext())
{
var orders = dbContext.Orders.OrderBy(o => o.CreateDateTime); var futureCount = orders.DeferredCount().FutureValue(); var futurePagerOrders = orders.Skip((pageIndex - ) * pageSize).Take(pageSize).Future(); totalCount = futureCount.Value; return futurePagerOrders.ToList();
}
} private static void FindGoodsMaxWithMinUnitPrice()
{
using (var dbContext = new EntityFrameworkPlusDbContext())
{
var futureMaxGoodsUnitPrice = dbContext.Goodses.DeferredMax(g => g.UnitPrice).FutureValue<decimal>();
var futureMinGoodsUnitPrice = dbContext.Goodses.DeferredMin(g => g.UnitPrice).FutureValue<decimal>();
var maxGoodsUnitPrice = futureMaxGoodsUnitPrice.Value;
var minGoodsUnitPrice = futureMaxGoodsUnitPrice.Value;
}
} }
}

2.  3个方法的SQL追踪和截图

FindOrdersWithGoodsies
-- EF+ Query Future: 1 of 2
SELECT
[Extent1].[OrderGuid] AS [OrderGuid],
[Extent1].[OrderNo] AS [OrderNo],
[Extent1].[OrderCreator] AS [OrderCreator],
[Extent1].[OrderDateTime] AS [OrderDateTime],
[Extent1].[OrderStatus] AS [OrderStatus],
[Extent1].[Description] AS [Description],
[Extent1].[Creator] AS [Creator],
[Extent1].[CreateDateTime] AS [CreateDateTime],
[Extent1].[LastModifier] AS [LastModifier],
[Extent1].[LastModifiedDateTime] AS [LastModifiedDateTime]
FROM [dbo].[Sample_Order] AS [Extent1] -- EF+ Query Future: 2 of 2
SELECT
[Extent1].[GoodsGuid] AS [GoodsGuid],
[Extent1].[GoodsNo] AS [GoodsNo],
[Extent1].[GoodsName] AS [GoodsName],
[Extent1].[GoodsBrand] AS [GoodsBrand],
[Extent1].[UnitPrice] AS [UnitPrice],
[Extent1].[Description] AS [Description],
[Extent1].[Creator] AS [Creator],
[Extent1].[CreateDateTime] AS [CreateDateTime],
[Extent1].[LastModifier] AS [LastModifier],
[Extent1].[LastModifiedDateTime] AS [LastModifiedDateTime]
FROM [dbo].[Sample_Goods] AS [Extent1]

FindPagerOrders(int pageSize, int pageIndex, out int totalCount)

-- EF+ Query Future: 1 of 2
SELECT
[GroupBy1].[A1] AS [C1]
FROM ( SELECT
COUNT(1) AS [A1]
FROM [dbo].[Sample_Order] AS [Extent1]
) AS [GroupBy1] -- EF+ Query Future: 2 of 2
SELECT
[Extent1].[OrderGuid] AS [OrderGuid],
[Extent1].[OrderNo] AS [OrderNo],
[Extent1].[OrderCreator] AS [OrderCreator],
[Extent1].[OrderDateTime] AS [OrderDateTime],
[Extent1].[OrderStatus] AS [OrderStatus],
[Extent1].[Description] AS [Description],
[Extent1].[Creator] AS [Creator],
[Extent1].[CreateDateTime] AS [CreateDateTime],
[Extent1].[LastModifier] AS [LastModifier],
[Extent1].[LastModifiedDateTime] AS [LastModifiedDateTime]
FROM [dbo].[Sample_Order] AS [Extent1]
ORDER BY [Extent1].[CreateDateTime] ASC
OFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY

FindGoodsMaxWithMinUnitPrice()

-- EF+ Query Future: 1 of 2
SELECT
[GroupBy1].[A1] AS [C1]
FROM ( SELECT
MAX([Extent1].[UnitPrice]) AS [A1]
FROM [dbo].[Sample_Goods] AS [Extent1]
) AS [GroupBy1] -- EF+ Query Future: 2 of 2
SELECT
[GroupBy1].[A1] AS [C1]
FROM ( SELECT
MIN([Extent1].[UnitPrice]) AS [A1]
FROM [dbo].[Sample_Goods] AS [Extent1]
) AS [GroupBy1]

至此比较常用到场景,就已经实作完成,大家看到截图和SQL说明都是一次执行,其他大家可以根据 EntityFramework Plus 源代码和文档(不过是英文,但是基本能够看懂),进行更加深入的了解,了解实现原理,我这里还是抛砖引玉一下。

这篇博文的源代码:https://github.com/haibozhou1011/EntityFramework-PlusSample

第二篇 Entity Framework Plus 之 Query Future的更多相关文章

  1. 第三篇 Entity Framework Plus 之 Query Cache

    离上一篇博客,快一周,工作太忙,只能利用休息日来写一些跟大家分享,Entity Framework Plus 组件系列文章,之前已经写过两篇 第一篇 Entity Framework Plus 之 A ...

  2. 第一篇 Entity Framework Plus 之 Audit

    一般系统会有登陆日志,操作日志,异常日志,已经满足大部分的需求了.但是有时候,还是需要Audit 审计日志,审计日志,主要针对数据增,改,删操作数据变化的记录,主要是对数据变化的一个追踪过程.其中主要 ...

  3. 第四篇 Entity Framework Plus 之 Batch Operations

    用 Entity Framework  进行 增,删,改.都是基于Model进行的,且Model都是有状态追踪的.这样Entity Framework才能正常增,删,改. 有时候,要根据某个字段,批量 ...

  4. .NET基础篇——Entity Framework 数据转换层通用类

    在实现基础的三层开发的时候,大家时常会在数据层对每个实体进行CRUD的操作,其中存在相当多的重复代码.为了减少重复代码的出现,通常都会定义一个共用类,实现相似的操作,下面为大家介绍一下Entity F ...

  5. Entity Framework Plus 系列目录

    Entity Framework Plus 系列文章计划的已经全部写完,可能还有其他功能没有写到,希望大家能够多动手,尝试一下使用,一定会给您带来一些帮助的.文章全部写完,也应该出一个目录方便查看,目 ...

  6. Code First :使用Entity. Framework编程(8) ----转发 收藏

    第8章 Code First将走向哪里? So far, this book has covered all of the Code First components that reached the ...

  7. Entity Framework 6.1-Code First【转】

      Entity Framework 6.1-Code First 分类: Entity Framework 2014-04-21 14:56 2034人阅读 评论(0) 收藏 举报 entityen ...

  8. entity framework 时间操作

    ).FirstOrDefault(); if (useractiveentity == null) { UserActive userActive = new UserActive(); userAc ...

  9. Managing DbContext the right way with Entity Framework 6: an in-depth guide by mehdime

    UPDATE: the source code for DbContextScope is now available on GitHub: DbContextScope on GitHub. A b ...

随机推荐

  1. 【Oracle 集群】ORACLE DATABASE 11G RAC 知识图文详细教程之集群概念介绍(一)

    集群概念介绍(一)) 白宁超 2015年7月16日 概述:写下本文档的初衷和动力,来源于上篇的<oracle基本操作手册>.oracle基本操作手册是作者研一假期对oracle基础知识学习 ...

  2. 简记用ArcGIS处理某项目需求中数据的步骤

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1. 背景 项目需求涉及如下几个步骤: a.矢量化 b.获取范围内要素 ...

  3. (整理)MyBatis入门教程(一)

    本文转载: http://www.cnblogs.com/hellokitty1/p/5216025.html#3591383 本人文笔不行,根据上面博客内容引导,自己整理了一些东西 首先给大家推荐几 ...

  4. swift 可选类型(optional)--- swift 入门

    一.思维导图 二.代码 //这样无形中就会让代码很丑陋 if x != nil && y != nil { print("x或y都不等于空") } print(&q ...

  5. C++常考面试题汇总

    c++面试题 一 用简洁的语言描述 c++ 在 c 语言的基础上开发的一种面向对象编程的语言: 应用广泛: 支持多种编程范式,面向对象编程,泛型编程,和过程化编程:广泛应用于系统开发,引擎开发:支持类 ...

  6. Linux.NET学习手记(8)

    上一回合中,我们讲解了Linux.NET面对OWIN需要做出的准备,以及介绍了如何将两个支持OWIN协议的框架:SignalR以及NancyFX以OwinHost的方式部署到Linux.NET当中.这 ...

  7. MapReduce剖析笔记之七:Child子进程处理Map和Reduce任务的主要流程

    在上一节我们分析了TaskTracker如何对JobTracker分配过来的任务进行初始化,并创建各类JVM启动所需的信息,最终创建JVM的整个过程,本节我们继续来看,JVM启动后,执行的是Child ...

  8. 我们为什么不能只用O记号来谈论算法?

    在刷LeetCode-1TwoSum的时候,有个人在论坛留言,大致意思如下: 我的算法击败了90%的人,O(nlgn)算法比O(n)算法快. 我觉得这个人是不懂算法的.让我一步一步解释. # O的含义 ...

  9. Java回调方法详解

    回调在维基百科中定义为: 在计算机程序设计中,回调函数,是指通过函数参数传递到其他代码的,某一块可执行代码的引用. 其目的是允许底层代码调用在高层定义的子程序. 举个例子可能更明白一些:以Androi ...

  10. Linux Nano命令

    Nano命令指南 今天在输命令时,无意中输入了nano,对这个命令不太熟悉,结果不知道如何才能退出,保存,赶快查了一下资料,原来是这样的啊. 打开文件与新建文件 使用nano打开或新建文件,只需键入: ...