过去我们常常使用Where或First(FirstOrDefault)方法来查找对应的实体,比如:

  1. var query = context.CertInfoMakeDetails.ToList().Where(make => int.Parse(make.CertCode) >= startcode &&
  2. int.Parse(make.CertCode) <=
  3. (startcode + count - 1) &&
  4. make.ProductName == productName);
var query = context.CertInfoMakeDetails.ToList().Where(make => int.Parse(make.CertCode) >= startcode &&
int.Parse(make.CertCode) <=
(startcode + count - 1) &&
make.ProductName == productName);

这样做的缺点是:即使我们相应的实体已经被DbContext缓存,EF还是会去执行数据库访问,而数据库访问是被普遍认为比较耗费性能的。

从EF4.1开始,微软为我们提供了一个新的API:DbSet<>.Find(),它可以帮助我们通过主键来查找对应的实体。并且如果相应的实体已经被DbContext缓存,EF会在缓存中直接返回对应的实体,而不会执行数据库访问。

比如我们查找证书ID为"101"的实体:

  1. var query = context.CertInfoMakeDetails.Find("101");
var query = context.CertInfoMakeDetails.Find("101");

也可以使用联合主键(比如查找CertCode = "101", ProductName = "ABC")的实体:

  1. var query = context.CertInfoMakeDetails.Find("101", "ABC");
var query = context.CertInfoMakeDetails.Find("101", "ABC");

注意:此处输入联合主键的次序需要按照我们定义改实体类时声明主键的次序。

和之前使用Where或First调用不同,Find也可以找到刚刚新增的实体:

  1. using (var context = new MyContext())
  2. {
  3. context.CertInfoMakeDetails.Add(new CertInfoMakeDetail {....});
  4. var newOne = context.Find(“Id”);
  5. }
using (var context = new MyContext())
{
context.CertInfoMakeDetails.Add(new CertInfoMakeDetail {....});
var newOne = context.Find(“Id”);
}

最后让我们来看看Find是如何实现的:

  1. public TEntity Find(params object[] keyValues)
  2. {
  3. this.InternalContext.ObjectContext.AsyncMonitor.EnsureNotEntered();
  4. this.InternalContext.DetectChanges(false);
  5. WrappedEntityKey key = new WrappedEntityKey(this.EntitySet, this.EntitySetName, keyValues, "keyValues");
  6. object obj2 = this.FindInStateManager(key) ?? this.FindInStore(key, "keyValues");
  7. if ((obj2 != null) && !(obj2 is TEntity))
  8. {
  9. throw System.Data.Entity.Resources.Error.DbSet_WrongEntityTypeFound(obj2.GetType().Name, typeof(TEntity).Name);
  10. }
  11. return (TEntity) obj2;
  12. }
public TEntity Find(params object[] keyValues)
{
this.InternalContext.ObjectContext.AsyncMonitor.EnsureNotEntered();
this.InternalContext.DetectChanges(false);
WrappedEntityKey key = new WrappedEntityKey(this.EntitySet, this.EntitySetName, keyValues, "keyValues");
object obj2 = this.FindInStateManager(key) ?? this.FindInStore(key, "keyValues");
if ((obj2 != null) && !(obj2 is TEntity))
{
throw System.Data.Entity.Resources.Error.DbSet_WrongEntityTypeFound(obj2.GetType().Name, typeof(TEntity).Name);
}
return (TEntity) obj2;
}

首先,EF调用了EnsureNotEntered() 方法来检查内部ObjectContext的状态,如果这个实例当前获得了一个排它锁,那么就抛出异常。之后调用DetectChanges 方法来同步了对象状态。WrappedEntityKey 主要用来将Find函数的参数包装成一个KeyValuePair。

之后,Find 方法首先调用 FindInStateManager 方法在缓存中进行查找,如果找不到对应的实体,那么就调用 FindInStore 在对数据库进行查找,如果仍然找不到,就抛出异常,否则返回对应实体。

Entity Framework API介绍 -- DbSet<>().Find()的更多相关文章

  1. Entity Framework Core介绍(1)

    介绍 Entity Framework (EF) Core 是轻量化.可扩展和跨平台版的常用 Entity Framework 数据访问技术. EF Core 可用作对象关系映射程序 (O/RM),以 ...

  2. Entity Framework开发介绍

    一.Entity Framework概要 Entity Framework是微软的Object Relational Mapper(对象关系映射),也就是我们平常说的ORM,它可以让应用程序开发者将关 ...

  3. Entity Framework相关介绍

    在深入学习某项技术之前,应该努力形成对此技术的总体印象,并了解其基本原理,本文的目的就在于此. 一.理解EF数据模型 EF本质上是一个ORM框架,它需要把对象映射到底层数据库中的表,为此,它使用了三个 ...

  4. Entity Framework 6:专家版本

    随着 Entity Framework 最新主版本 EF6 的推出,Microsoft 对象关系映射 (ORM) 工具达到了新的专业高度,与久负盛名的 .NET ORM 工具相比已不再是门外汉. EF ...

  5. 基于Entity Framework 6的框架Nido Framework

    随着 Entity Framework 最新主版本 EF6 的推出,Microsoft 对象关系映射 (ORM) 工具达到了新的专业高度,与久负盛名的 .NET ORM 工具相比已不再是门外汉. EF ...

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

    Chapter6 Controlling Database Location,Creation Process, and Seed Data 第6章 控制数据库位置,创建过程和种子数据 In prev ...

  7. Entity Framework Core 执行SQL语句和存储过程

    无论ORM有多么强大,总会出现一些特殊的情况,它无法满足我们的要求.在这篇文章中,我们介绍几种执行SQL的方法. 表结构 在具体内容开始之前,我们先简单说明一下要使用的表结构. public clas ...

  8. ABP官方文档翻译 9.2 Entity Framework Core

    Entity Framework Core 介绍 DbContext 配置 在Startup类中 在模块PreInitialize方法中 仓储 默认仓储 自定义仓储 应用程序特定基础仓储类 自定义仓储 ...

  9. Lerning Entity Framework 6 ------ Defining the Database Structure

    There are three ways to define the database structure by Entity Framework API. They are: Attributes ...

随机推荐

  1. flowable DmnEngine和DmnEngineConfiguration

    一.DmnEngineConfiguration创建实例 DmnEngineConfiguration 提供了7个公共的静态方法,用于创建自身实例. 其中5个是使用spring的机制加载配置文件. 另 ...

  2. Mac OS 升级到10.12问题 Android ADT 下载SDK问题 https://dl-ssl.google.com refused...

    缘由: 更新sdk,遇到了更新下载失败问题: Fetching https://dl-ssl.google.com/android/repository/addons_list-2.xml Fetch ...

  3. 深度学习(六十九)darknet 实现实验 Compressing Deep Neural Networks with Pruning, Trained Quantization and Huffma

    本文主要实验文献文献<Deep Compression: Compressing Deep Neural Networks with Pruning, Trained Quantization ...

  4. 1. Java EE简介 - JavaEE基础系列

    什么是Java EE? 真的是你理解的那样吗? Java EE, 原名J2EE, 其核心由一系列抽象的标准规范所组成, 是针对目前软件开发中所普遍面临问题的解决方案. 注意以上定义中的"抽象 ...

  5. 使用 $scope.$apply 手动更新页面数据

    注意 $scope.$apply  调用时的位置

  6. Java从入门到精通全套教程免费分享

    这是我自己早前听课时整理的Java全套知识,适用于初学者,也可以适用于中级进阶的人,你们可以下载,我认为是比较系统全面的,可以抵得上市场上90%的学习资料.讨厌那些随便乱写的资料还有拿出来卖钱的人!在 ...

  7. gulp使用 实现文件修改实时刷新

    gulp例子:https://github.com/Aquarius1993/gulpDemo 淘宝镜像:$ npm install -g cnpm --registry=https://regist ...

  8. vue项目更改端口号

    vue项目的默认端口为8080,有时候处于某些原因会造成端口号的冲突,因此需要我们适当的更改其端口号来解决问题,将上图中的port更改为合适的端口号就可以,但是需要注意的是浏览器的安全限制端口号详情见 ...

  9. JAVA多线程----用--进阶--》网络编程2

    import java.io.*; import java.net.*; /** * 服务器端逻辑线程 */ public class LogicThread extends Thread { Soc ...

  10. 一次Mysql连接池卡死导致服务无响应问题分析(.Net Mysql.Data 6.9.9)

    问题: 进程启动后,线程数迅速上升至最小线程数后,缓慢上升(线程池限制)到数千,然后由于线程过多,CPU飙升到90%. 对外表现为Api无响应或连接超时. 背景 有些数据存在于另一个机房,通过内网专线 ...