原文:http://blog.csdn.net/eqera/article/details/8411437

这是这了系列的最后一篇,我将讨论如何绕过 EF 的查询映射。

像所有优秀的框架一样,EF 知道它并不能优秀到覆盖所有的角落,通过允许直接访问数据库,EF 支持开放底层的 ADO.NET 框架。

有三个 API 支持:

  • DbContext.Database.ExecuteSqlCommand
  • DbContext.Database.SqlQuery
  • DbSet.SqlQuery

第一个没有什么特别,就像典型的 ADO.NET 中的 SqlCommand。

publicint ExecuteSqlCommand(string sql, paramsobject[] parameters);

第二个有点意思。

public IEnumerable<TElement> SqlQuery<TElement>(string sql, paramsobject[] parameters);

我们可以使用这个方法直接将 SQL 命令发送到数据库,不管是存储过程,还是临时的 SQL。与 ADO.NET 的区别在于它能够将查询结果的 DataReader 中的数据直接转换为实体对象。

TElement 可以是任何类。重要的是 EF 不会跟踪返回的对象,即使他们真的是实体类型的对象。这与第三个 DbSet 不同,第三种方式会跟踪返回的对象。

让我们试一下 DbContext.Database.SqlQuery:

public IEnumerable<SprocReport> GetEntityList() 

return Database.SqlQuery<SprocReport>("SELECT LegalEntityBaseID, EntityName FROM dbo.LegalEntity"); 
}

一个最佳实践就是在 DbContext 的派生类中封装这些调用。下面是我们使用的 SprocReport 类的定义。

publicclass SprocReport 

publicint LegalEntityBaseID { get; set; } 
publicstring EntityName { get; set; } 
}

这个类不是实体,而且属性被直接映射:不能控制映射。即使你使用复杂类型,并且覆盖了映射,这些覆盖也不会起作用。

现在看 DbSet.SqlQuery,这个方法返回的实体将会被 EF 跟踪修改,所以,如果你在这些返回的实体上做了修改,当 DbContext.SaveChanges 被调用的时候,将会被处理。从另一个方面来说,也不能覆盖列的映射。

另外一个旁路 EF 映射管理的方法是使用 Entity SQL,记住 EF 将实体模型映射到物理的模型,在转换到本地底层的数据存储(例如 TSQL) 查询之前,先将 LINQ 查询被转化到实体模型上(通过 eSQL 语法)。

举例来说,我们可以创建实体集而不需要在 DbContex 中定义:

 
protectedoverridevoid OnModelCreating(DbModelBuilder modelBuilder) 

base.OnModelCreating(modelBuilder);  modelBuilder.Entity<SimpleEntry>().HasEntitySetName("MyEntry"); 
modelBuilder.Entity<SimpleEntry>().ToTable("MyEntry", "man"); 
modelBuilder.Entity<SimpleEntry>() 
.Property(s => s.ID) 
.HasColumnName("SimpleEntryID"); 
modelBuilder.Entity<SimpleEntry>() 
.Property(s => s.Name) 
.HasColumnName("SimpleEntryName");  }
 

然后,我们可以暴露出查询:

 
public IEnumerable<SimpleEntry> GetSimpleEntries() 

IObjectContextAdapter adapter =this; 
var entries = adapter.ObjectContext.CreateQuery<SimpleEntry>("SELECT VALUE MyEntry FROM MyEntry");  return entries; 
}
 

这里我们使用底层的 ObjectContext 以便查询。这种方式比直接将 SQL 发送到数据库的优势在于,我们可以使用 LINQ 在其上进行查询,最终发送到数据库的 SQL 是合并得到的。因此,我们可以通过从一个返回任何结果的简单查询开始,然后在其上应用 LINQ来得到有效的查询,而不需要在使用方查询整个表。

为了说服我们自己,我刚刚说的是真的,让我们试一下。

 
public IEnumerable<SimpleEntry> GetSimpleEntries() 

IObjectContextAdapter adapter =this; 
var entries = adapter.ObjectContext.CreateQuery<SimpleEntry>("SELECT VALUE MyEntry FROM MyEntry"); 
var final = from e in entries 
where e.Name == "Mark" 
select e; 
var f = (System.Data.Objects.ObjectQuery<SimpleEntry>)final; 
var s = f.ToTraceString();  return entries; 
}
 

如果输出 s 的值,可以看到:

SELECT 
[Extent1].[SimpleEntryID]AS[SimpleEntryID], 
[Extent1].[SimpleEntryName]AS[SimpleEntryName] 
FROM[man].[MyEntry]AS[Extent1] 
WHERE N’Mark’ = [Extent1].[SimpleEntryName]

这是 EF 生成的典型的 TSQL, 你会注意到 LINQ 过滤条件被应用到了 SQL 语句中。

现在,如果你希望能够截获实体的 Insert, Update, 和 Delete 操作,就要靠你自己了。你需要重写 DbContext.SaveChanges ,获取特定状态的实体,实现自己的数据操作逻辑来保存修改,然后在调用 base.SaveChanges 之前将这些实体的状态切换到 Unmodified 。这可以用,但这是一种特殊的技巧。

Entity Framework 4.1 绕过 EF 查询映射的更多相关文章

  1. 转载Entity Framework 5.0(EF first)中的添加,删除,修改,查询,状态跟踪操作

    转载原出处:http://www.cnblogs.com/kenshincui/p/3345586.html Entity Framework将概念模型中定义的实体和关系映射到数据源,利用实体框架可以 ...

  2. 【EF】Entity Framework Core 软删除与查询过滤器

    本文翻译自<Entity Framework Core: Soft Delete using Query Filters>,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 注意 ...

  3. EF框架组件详述【Entity Framework Architecture】(EF基础系列篇3)

    我们来看看EF的框架设计吧: The following figure shows the overall architecture of the Entity Framework. Let us n ...

  4. Entity Framework Core 软删除与查询过滤器

    本文翻译自<Entity Framework Core: Soft Delete using Query Filters>,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 注意 ...

  5. Entity Framework(实体框架 EF)

    什么是Entity Framework呢(下面简称EF)? EF(实体框架)是ADO.NET中的一组支持开发面向数据的软件应用程序的技术,是微软的一个ORM框架.ORM(对象关系映射框架):指的是面向 ...

  6. 安装Entity Framework【Setup Entity Framework Environment】(EF基础系列篇4)

    Entity Framework 5.0 API是分布在两个地方:NuGet和.NET Framework中,这个.NET framework 4.0/4.5包含EF核心的API,然而通过NuGet包 ...

  7. Entity Framework学习笔记——配置EF

    初次使用Entity Framework(以下简称EF),为了避免很快忘记,决定开日志记录学习过程和遇到的问题.因为项目比较小,只会用到EF的一些基本功能,因此先在此处制定一个学习目标:1. 配置EF ...

  8. Entity Framework 使用注意:Where查询条件中用到的关联实体不需要Include

    来自博客园开发团队开发前线最新消息: 在Entity Framework中,如果实体A关联了实体B,你想在加载实体A的同时加载实体B.通常做法是在LINQ查询中使用Include().但是,如果你在查 ...

  9. Entity Framework Code First使用DbContext查询

    DbContext.DbSet及DbQuery是Entity Framework Code First引入的3个新的类,其中DbContext用于保持数据库会话连接,实体变化跟踪及保存,DbSet用于 ...

随机推荐

  1. Swift - 39 - 枚举类型关联默认值

    //: Playground - noun: a place where people can play import UIKit enum Month: Int { // 这么定义, 后面的Feb, ...

  2. 有用的前端demo

    js定时器循环切换字体和背景颜色<script type="text/javascript"> var flashId = 0; setInterval(functio ...

  3. mysql 数据库字符串替换

    UPDATE `table_name` SET `field_name` = replace (`field_name`,'from_str','to_str') WHERE `field_name` ...

  4. Eclipse搭建struts2环境

    搭建struts2环境 大的方面分为三步: 1. 加入jar包 2. 在web.xml中配置struts2 3. 添加struts2的配置文件struts.xml 下面是详细步骤: 1. 新建一个Dy ...

  5. CURL请求接口

    private function  http_curl($url,$data=null){ //1.初始化,创建一个新cURL资源                 $ch = curl_init(); ...

  6. SQL Server 触发器(转)

    触发器是一种特殊类型的存储过程,它不同于之前的我们介绍的存储过程.触发器主要是通过事件进行触发被自动调用执行的.而存储过程可以通过存储过程的名称被调用. Ø 什么是触发器 触发器对表进行插入.更新.删 ...

  7. C程序设计语言练习题1-18

    练习1-18 编写一个程序,删除每个输入行末尾的空格及制表符,并删除完全是空格的行. 代码如下: #include <stdio.h> // 包含标准库的信息. #define MAXLI ...

  8. 【学习笔记】【oc】类的包装类 协议 category

    1.类的两种包装类: 将基本数据包装成对象:NSValue:NSNumber; NSValue是NSNumber的父类, NSValue用来封装一些基本数据, NSValue是一个通用的包装类,用来包 ...

  9. MacOS上的包管理工具

    众所周知,Linux世界中存在着如apt-get.yum等强大而简单的包管理工具,而在Macos中同样存在类似的东西. 当前比较流行的主要有如下两种: 1.Homebrew(推荐):其官网地址brew ...

  10. ECMA 6 记入

    好书推荐 : http://es6.ruanyifeng.com/ String.prototype -includes, startsWith, endsWith -padStart, padEnd ...