码迷,mamicode.com
首页 > 其他好文 > 详细

Entity Framework 4.1 之八:绕过 EF 查询映射

时间:2017-02-19 15:15:58      阅读:195      评论:0      收藏:0      [点我收藏+]

标签:存储过程   object   hive   另一个   context   sql   数据存储   不同   reader   

原文名称:Entity Framework 4.1: Bypassing EF query mapping (8)

原文地址:http://vincentlauzon.wordpress.com/2011/04/21/entity-framework-4-1-bypassing-ef-query-mapping-8/

看到 Entity Framework 4.1 推荐英文教程,为了帮大家看起来方便一些,简单翻译一下。这是一个系列,共有 8 篇,这是第 8 篇。
 
  1. Entity Framework 4.1 之一 : 基础
  2. Entity Framework 4.1 之二 : 覆盖默认的约定
  3. Entity Framework 4.1 之三 : 贪婪加载和延迟加载
  4. Entity Framework 4.1 之四:复杂类型
  5. Entity Framework 4.1 之五:多对多的关系
  6. Entity Framework 4.1 之六:乐观并发
  7. Entity Framework 4.1 之七:继承
  8. Entity Framework 4.1 之八:绕过 EF 查询映射

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

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

有三个 API 支持:

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

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

public int ExecuteSqlCommand( string sql, params object [] parameters);

第二个有点意思。

public IEnumerable < TElement > SqlQuery < TElement > ( string sql, params object [] 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 类的定义。

public class SprocReport
{
public int LegalEntityBaseID { get ; set ; }
public string EntityName { get ; set ; }
}

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

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

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

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

protected override void 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 。这可以用,但这是一种特殊的技巧。

参考页面:

http://www.yuanjiaocheng.net/ASPNET-CORE/core-view-start.html

http://www.yuanjiaocheng.net/webapi/webapi-filters.html

http://www.yuanjiaocheng.net/CSharp/csharp-dynamic-type.html

http://www.yuanjiaocheng.net/CSharp/Csharp-Exception.html

http://www.yuanjiaocheng.net/CSharp/csharp-generic-dictionary.html

http://www.yuanjiaocheng.net/Linq/linq-query-syntax.html

http://www.yuanjiaocheng.net/ASPNET-CORE/first.html

http://www.yuanjiaocheng.net/mvc/mvc-helper-textbox.html

http://www.yuanjiaocheng.net/ASPNET-CORE/core-authorize-attribute.html

http://www.yuanjiaocheng.net/CSharp/csharp-array.html

http://www.yuanjiaocheng.net/CSharp/Csharp-sortedlist.html

Entity Framework 4.1 之八:绕过 EF 查询映射

标签:存储过程   object   hive   另一个   context   sql   数据存储   不同   reader   

原文地址:http://www.cnblogs.com/wangxiaobingya/p/6415760.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!