过去我们常常使用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. Shell 从日志文件中选择时间段内的日志输出到另一个文件

    Shell 从日志文件中选择时间段内的日志输出到另一个文件 情况是这样的,某系统的日志全部写在一个日志文件内,所以这个文件非常大,非常长,每次查阅的时候非常的不方便.所以,相关人员希望能够查询某个时间 ...

  2. [Scala]Scala学习笔记四 类

    1. 简单类与无参方法 class Person { var age = 0 // 必须初始化字段 def getAge() = age // 方法默认为公有的 } 备注 在Scala中,类并不声明为 ...

  3. [置顶] 滴滴插件化VirtualAPK框架原理解析(二)之Service 管理

    在前一篇博客滴滴插件化框架VirtualAPK原理解析(一)之插件Activity管理 中VirtualAPK是如何对Activity进行管理的,本篇博客,我们继续来学习这个框架,这次我们学习的是如何 ...

  4. java入门学习(3)—循环,选择,基础算法,API概念

    1.顺序结构:也就是顺着程序的前后关系,依次执行.2.选择分支:利用if..else , / switch(){case [ 这个必须是常量]:}; / if..else if….. ….else.. ...

  5. JDiPad项目runtime的使用分析

    首先,项目有点老 但是运行还是没有问题的.其中很多地方到了runtime,同时也看到了 早期的开发人员 基本没用pod 第三方也很少用,除了微信登录,整个项目还没看到集成的第三方SDK.然后慢慢梳理 ...

  6. Android中的sp和wp指针

    经常会在android的framework代码中发现sp<xxx>和wp<xxx>这样的指针,平时看的时候都把他当成一个普通的指针封装过掉了,这几天终于忍不住了,想深入了解一下 ...

  7. python 两种导入的区别

    参考文献: 法1:import module1 使用:这样你调用时就得:module1.funct(),funct2(),... 法2:from module1 import funct() 使用就直 ...

  8. sqlserver获取代理服务作业job的执行情况

    以下脚本为获取sqlserver的执行job with testtemp as( SELECT sch.job_id,--his.[server] as InstanceName CONVERT(nv ...

  9. PDF文档过期时间/自毁设置

    不是很完美的方法,可以凑活着用: 切换到Pages预览页,右击页面选页面属性 切换到Action,选Run a Javascript,代码: // PDF JavaScript to make it ...

  10. HDU - 4339: Query(bitset暴力找下一个为1的)

    题意:给定A,B长度相同的字符串,Q次操作,修改操作位单个字符修改,查询操作为询问从某点开始有多少连续相同的字符. 思路:我们把不相同的设为1,相同的设为0,那么询问就是找下一个为1的为位置,可以用线 ...