过去我们常常使用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. pip安装tensorflow出错怎么办

    随着人工智能的开发越来越多人参与,现在下载tensorflow 1.2版本也经常出错了,如下: 这时怎么办呢? 其实比较简单,可以通过pypi的网站来下载: https://pypi.python.o ...

  2. postgresql的now()与Oracle的sysdate

    postgresql的now()为当前事务开始时间, 而Oracle的sysdate是当前时间. 区别在于事务. postgresql中的now(): postgres=# begin ; BEGIN ...

  3. linux环境搭建记录

    第一次搭建环境,部署服务,在此记录一下过程 1.项目用到的hosts设置好 2.mkdir data,在data文件夹下建server,log,soft,resource路径,上载jdk.zip到so ...

  4. Python源码分析(一)

    最近想学习下Python的源码,希望写个系列博客,记录的同时督促自己学习. Python源码目录 从Python.org中下载源代码压缩包并解压,我下载的是Python2.7.12,解压后: 对于主要 ...

  5. 【pandas】pandas.to_datatime()---时间格式转换

    标准时间格式:2012-12-21 时间转换函数:pandas.to_datatime() # -*- coding: utf- -*- # 生成数据 import pandas as pd data ...

  6. python的文件编码注释

    在python源文件的第一行或第二行写入如下内容: # -*- coding:gbk -*- # 设置源文件编码格式为gbk 或 # -*- coding:utf-8 -*- # 设置源文件编码格式为 ...

  7. ffpmeg下rtmp踩坑记录

    1. flash端发布直播流 2.在 ffplay 命令行中 播放rtmp 直播流 ffplay "rtmp://127.0.0.1:80/live/ss live=1"  一直出 ...

  8. BZOJ1015: [JSOI2008]星球大战starwar【并查集】【傻逼题】

    Description 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系.某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球.这些星球通过 ...

  9. flask第十七篇——模板【1】

    从这一节开始我们就正式进入flask一个重要的模块——模板了. 我们平时看的知乎平台就是Python开发的,可以看到他的很多页面布局都是一样的,比如你现在搜“如何自学Python”,去知乎看他的页面是 ...

  10. 转:Excel导入SQL数据库完整代码

    Excel导入SQL数据库完整代码 protected void studentload_Click(object sender, EventArgs e) {//批量添加学生信息 SqlConnec ...