过去我们常常使用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. (转)JAVA正则表达式语法大全

    [正则表达式]文本框输入内容控制 整数或者小数:^[0-9]+\.{0,1}[0-9]{0,2}$ 只能输入数字:"^[0-9]*$". 只能输入n位的数字:"^\d{n ...

  2. 更换pip源,解决pip install安装包慢的问题

    而pip是很强大的Python包安装工具,但是由于国外官方pypi经常被墙,导致不可用,所以最好是将使用的pip源更换一下,这样就能解决被墙导致的装不上库的问题.网上有很多可用的源,例如豆瓣:http ...

  3. Python的安装与设置

    1.Python的下载与安装最新的python 版本下载可以去python的网站进行下载 . 考虑系统兼任这里下载32位的Python 双击下载的exe文件进行安装 单击Next 完成Python 安 ...

  4. QUnit使用

    什么是单元测试 每个单元测试就是一段用于测试一个模块或接口是否能达到预期结果的代码. QUnitjs 概念Qunit是一款强大的用于帮助调试代码的,JavaScript单元测试框架.是jQuery的官 ...

  5. weight decay (权值衰减)

    http://blog.sina.com.cn/s/blog_890c6aa30100z7su.html 在机器学习或者模式识别中,会出现overfitting,而当网络逐渐overfitting时网 ...

  6. eclipse如何通过git把项目上传到码云上

    转载:原文链接:https://www.cnblogs.com/yixtx/p/8310311.html 1.eclipse安装git插件 具体我也做过,因为我下载的eclipse版本以及由git插件 ...

  7. Web应用中使用JavaMail发送邮件进行用户注册

    现在很多的网站都提供有用户注册功能, 通常我们注册成功之后就会收到一封来自注册网站的邮件.邮件里面的内容可能包含了我们的注册的用户名和密码以及一个激活账户的超链接等信息.今天我们也来实现一个这样的功能 ...

  8. 《DSP using MATLAB》示例Example6.2

    2017年了,阳历新年都11号了,已从外地回到家乡,依然苦逼的生活…… 接着写读书(Digital Signal Processing using MATLAB)笔记吧 代码: b = [1 -3 1 ...

  9. [Reship] Mean Shift 算法介绍

    ==================================================================================== This article ca ...

  10. dockerize 容器工具集基本使用

    基本功能:   *  在启动的时候根据环境变量或者模版生成配置文锦啊 *   多日志文件重定向到标准输入输出 *   等待其他服务(tcp,http unix)起来之后在启动主进程   1. 安装 直 ...