第二篇 Entity Framework Plus 之 Query Future

小分享:我有几张阿里云优惠券,用券购买或者升级阿里云相应产品最多可以优惠五折!领券地址:https://promotion.aliyun.com/ntms/act/ambassador/sharetouser.html?userCode=ohmepe03



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

今天主要怎样减少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 - 1) * 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(50); this.Property(t => t.GoodsName) .IsRequired() .HasMaxLength(50); this.Property(t => t.GoodsBrand) .IsRequired() .HasMaxLength(50); this.Property(t => t.Creator) .IsRequired() .HasMaxLength(20); this.Property(t => t.LastModifier) .HasMaxLength(20); // 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 - 1) * 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

参考页面:http://qingqingquege.cnblogs.com/p/5933752.html

时间: 2024-10-05 07:19:25

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

第一篇 Entity Framework Plus 之 Audit

一般系统会有登陆日志,操作日志,异常日志,已经满足大部分的需求了.但是有时候,还是需要Audit 审计日志,审计日志,主要针对数据增,改,删操作数据变化的记录,主要是对数据变化的一个追踪过程.其中主要追踪数据关键点如下 1. 新增 具体新增哪些数据,值是什么,新增人谁. 2. 修改 具体修改哪些数据,之前值是什么,修改后值是什么,修改人谁. 3. 删除 具体删除哪些数据,之前值是什么,删除人谁. 有了这个Audit追踪过程,当那天,用户操作的数据出现问题,你就可以根据这个Audit将数据恢复到某

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

小分享:我有几张阿里云优惠券,用券购买或者升级阿里云相应产品最多可以优惠五折!领券地址:https://promotion.aliyun.com/ntms/act/ambassador/sharetouser.html?userCode=ohmepe03 在实现基础的三层开发的时候,大家时常会在数据层对每个实体进行CRUD的操作,其中存在相当多的重复代码.为了减少重复代码的出现,通常都会定义一个共用类,实现相似的操作,下面为大家介绍一下Entity Framework时常用到的通用类.首先在数据

第二章 Entity Framework -- Code First入门

前言 我们在开发项目的时候,项目可能已经有了对应的数据库,也可能完全没有数据库需要我们从零开始,还有可能是我们收下了一个别人的烂摊子,需要我们自己做些修正.说真的,无论什么还是原装的比较好一点.现在先看下,如何不使用任何配置文件和注释代码(注解)实现,EF操作数据库. 第一节 从零开始,使用EF自动创建 1.根据你的需要,创建一个项目 2.在启动项目中的config文件添加一个指向目标数据库的连接字符串,数据库是否存在没有任何关系. 3.编写若干实体类,编写属性.这里有一个注意的地方:主键属性必

Entity Framework Plus 系列目录

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

Entity Framework初探

参考页面: http://www.yuanjiaocheng.net/entity/change-tracking.html http://www.yuanjiaocheng.net/entity/Persistence-in-EF.html http://www.yuanjiaocheng.net/entity/crud-in-connected.html http://www.yuanjiaocheng.net/entity/crud-in-Disconnected.html http://

Entity Framework 6.1-Code First【转】

Entity Framework 6.1-Code First 分类: Entity Framework 2014-04-21 14:56 2034人阅读 评论(0) 收藏 举报 entityentity framework框架 Code First-代码优先,先创建好领域模型.新建MyDbContext继承DbContext.根据代码自动生成数据库 Code First优点 1.可以自由的创建领域模型,基本不受EF框架的限制.自由的命名.程序员只需要关心对象间的关系.基本做到了与数据库的完全分

第二篇:Entity Framework CodeFirst &amp; Model 映射

小分享:我有几张阿里云优惠券,用券购买或者升级阿里云相应产品最多可以优惠五折!领券地址:https://promotion.aliyun.com/ntms/act/ambassador/sharetouser.html?userCode=ohmepe03 前一篇 第一篇:Entity Framework 简介 我有讲到,ORM 最关键的 Mapping,也提到了最早实现Mapping的技术,就是 特性 + 反射,那Entity Framework 实现Mapping 又是怎样的呢? Entity

Entity Framework基础—第二篇

实体框架(Entity Framework) 简称EF,属于数据持久(持久保存)架里面的一种,其他的还有NHibernate,ibaties,Dapper.PetaPOCO...等,都是基于ORM思想. 首先介绍下O/R Mapping(ORM) 1.什么是ORM?ORM指的是面向对象的对象模型和关系数据库的数据结构之间的相互转化,可以理解为把表实体和表相互转化(在任何平台都适用,如php,java等). 传统ADO.net操作数据库: 基于ORM思想操作数据库: 接下来我们就一步步创建项目:

第一篇:Entity Framework 简介

先从ORM说起吧,很多年前,由于.NET的开源组件不像现在这样发达,更别说一个开源的ORM框架,出于项目需要,以及当时OOP兴起(总不至于,在项目里面全是SQL语句),就自己开始写ORM框架.要开发ORM框架首先要了解ORM概念. ORM 对象关系映射,O(Object) 对象,在项目中就是实体,更加精确的来说就是数据Model,也可以说持久化类.R(Relation) 关系数据,M (Mapping)映射,将对象映射到关系数据,将关系数据映射到对象的过程. 更加直观理解就是,ORM 就是以OO