Entity Framework

创建时间:
2014-01-04 23:25
最近更新:
2018-10-04 23:43

Overview

Entity Framework 是一种 ORM (Object Relational Mapping) 框架,它能把我们在编程时使用对象映射到底层的数据库结构。比如,你可以在数据库中建立一个 Order 表,让它与程序中的 Order 类建立映射关系,这样一来,程序中的每个 Order 对象都对应着 Order 表中的一条记录,ORM 框架负责把从数据库传回的记录集转换为对象,也可以依据对象当前所处的具体状态生成相应的 SQL 命令发给数据库,完成数据的存取工作 (常见的数据存取操作可简称为 CRUD Create、Read、Update、Delete)。

Entity Framework 以 Entity Data Model (EDM) 为主,将数据逻辑层切分为三块,分别为以下三层:

  • CSDL - Conceptual Schema Mapping
  • MSL - Mapping Concept and Storage Schema
  • SSDL - Storage Schema Mapping

其上还有 Entity Client, Object Context 以及 LINQ 可以使用。
在最新 4.1 版本中,增加了 DbContext API 及 Codefirst。
DbContext API 是基于 ObjectContext 和其他一些类型抽象出的一个简单的 API,并进行了优化。

Entity Framework 支持多种数据库,Tony 曾使用 MySQL、Oracle、SQL Server。

NuGet

https://www.nuget.org/packages/EntityFramework/
PM> Install-Package EntityFramework -Version 6.1.1

Resource - MSDN

  1. 实体框架 (Entrance of MSDN, 截至 2014-03-06 左侧目录树中有 EF5/6 两个版本的类库)
  2. 实体数据模型 (EDM Entity Data Model) (Build Date: 2012-08-02)
  3. ADO.NET (该页面左侧的导航中,有几个与 Entity Framework 相关)
  4. 数据开发 - 使用 Microsoft 的数据平台,面向 Web 服务器、企业服务器和云为移动设备和桌面创建以数据为中心的解决方案。
  5. 实体框架是 Microsoft 为新应用程序推荐的数据访问技术
  6. Data Access and Storage > 学习 > 实体框架
  7. 实体框架 (EF) 入门:
  8. EF Power Tools:
  9. 性能注意事项 (实体框架)
  10. 兵不血刃拒绝 Entity Framework 对表的访问

Resource

  1. 《Entity Framework 6 Recipes》 中文翻译系列 目录篇
  2. 为什么我需要 LINQ 与 Entity Framework
  3. Entity Framework 底层操作封装
  4. Entity Framework 技巧系列
  5. 新问题新方法:在 Entity Framework 中实现指定字段更新
  6. 概述 (金旭亮)
  7. Entity Framework 实例详解系列 - 田念明
  8. Entity Framework 快速入门
  9. MVC 实用架构设计
  10. 使用 EF 构建企业级应用 (一)
  11. ExtJS4.1 + MVC3 + Spring.NET1.3 + EF5 整合
  12. Entity Framework 技术导游系列
  13. 比较 NHibernate 和 Entity Framework
  14. 在 Entity Framework 中执行 T-sql 语句 之后 填充实体 的规则
  15. 如何向 OrderBy 传递字符串参数 (Entity Framework) (已整理在 TonyLibrary 中)
  16. EntityFramework.Extensions
  17. Entity Framework 之深入分析
  18. Entity Framework 实体框架的形成之旅 - 基于泛型的仓储模式的实体框架
  19. Entity Framework 扩展 - 批量插入
  20. 批量操作可显著提升 Entity Framework 的性能
  21. Entity Framework 映射的总结
  22. Entity Framework 查询原理
  23. EFProf - 用于跟踪 Entity Framework 发送到 SQL Server 中的 SQL 语句
  24. HasDefaultSchema() - Default Schema (EF6 onwards) - 从 EF6 开始可以使用 DbModelBuilder 中的方法 HasDefaultSchema 来指定所有的表/存储过程/视图等属于哪一个 database schema
  25. Entity Framework - 张占岭 随笔分类

Resource - 封装

  1. http://www.baidu.com/s?ie=utf-8&bs=Entity+Framework+%E5%B0%81%E8%A3%85&f=8&rsv_bp=1&wd=Entity+Framework+%E5%B0%81%E8%A3%85&inputT=0
  2. http://zzk.cnblogs.com/s?w=EF+%E5%B0%81%E8%A3%85&t=b
  3. http://www.cnblogs.com/yanzhiyuan928/p/3166994.html
  4. http://blog.csdn.net/jacky4955/article/details/9138629
  5. DB First 中对 Repository 层封装的几点小记
  6. Entity Framework 封装?
  7. Search "Entity Framework 封装" in google.com.
  8. Entity Framework 增删改查 - 通用数据库操作基类
  9. EF 架构 真正被封装的排序方法,支持多列排序
  10. 基于泛型的仓储模式的实体框架

Resource - Include()

  1. 本站文章 《金旭亮 Entity Framework 技术导游系列 (3)- CRUD (上)》
  2. Entity Framework - Include 使用 Lambda 表示式
  3. 如何及何时使用贪婪加载

Courses 和 OfficeAssignment 是导航属性,就像之前解释过的那样,它们通常被定义为 virtual 类型以便它们可以使用 Entity Framework 的延迟加载 (lazy loading) 功能。如果一个导航属性中包含有多个实体,则其类型必须实现 ICollection<T> 接口,例如 List<T> 而不是 IEnumerable<T>,因为 IEnumerable<T> 并没有实现 Add 方法。

一个 instructor 可以教多门 course,所以 Courses 被定义为 Course 实体的集合。
public virtual ICollection<Course> Courses { get; set; }

我们的业务规定一个 instructor 最多只能有一个 office,所以 OfficeAssignment 被定义为单个 OfficeAssignment 实体 (如果 instructor 没有 office,则赋值为 null)。
public virtual OfficeAssignment OfficeAssignment { get; set; }

-- http://blog.csdn.net/johnsonblog/article/details/39013469

扩展 - Entity Framework Extended Library

  1. Entity Framework Extended Library - A library the extends the functionality of Entity Framework (支持批量更新、删除、合并多个查询等)

EF 生成的 SQL

网友:"可以使用 Visual Studio 2010 Ultimate 所带的 IntelliTrace 功能或者 SQL Server Profiler 来得到 EF 所生成的 SQL。不过这两种方法只针对 SQL Server 和对应的 T-SQL。"。

EF 的四种开发模式

Code First (New DataBase) 在代码中定义类和映射关系并通过 model 生成数据库,使用迁移技术更新数据库。
Code First (Existing DataBase) 在代码中定义类和映射关系,给逆向工程提供工具。
Model First 在设计器中创建 Model,并用 Model 生成数据库。所有的类由 Model 自动生成。
DateBase First 在设计器中逆向生成 Model,并有 Model 自动生成所有的类。

System.Data.EntityState 枚举

http://msdn.microsoft.com/zh-CN/library/System.Data.EntityState

Description

The state of an entity object.
This enumeration has a FlagsAttribute attribute that allows a bitwise combination of its member values.

Namespace: System.Data
Assembly: System.Data.Entity (in System.Data.Entity.dll)
Syntax:

[BindableTypeAttribute(IsBindable = false)]
[FlagsAttribute]
public enum EntityState

Members

  1. Added
  2. Deleted
  3. Detached
  4. Modified
  5. Unchanged

MySQL & Entity Framework

详见本站专文。

支持多数据库

数据访问层,如果使用 EntityFramework 的话,本身 EF 就支持多数据库,只需要配置不同的数据库连接字符串,提供不同的 dbprovider。
如果是自己实现的数据访问层,那就要将不同数据库访问类都继承同一个接口。数据访问层只是依赖这个接口,这样就能让数据访问层和具体数据库之间解耦。
-- 本文 10 楼的评论

测试记录: 不能映射至 Tuple

using(var db = new DefaultDbContext()) {
    string sql = "...";
    var tuples = db.Database.SqlQuery<Tuple<DateTime, string, string, int>>(sql).ToArray();
    //上一行报错 "The result type 'System.Tuple`4[System.DateTime,System.String,System.String,System.Int32]' may not be abstract and must include a default constructor."。
    var anonymities = tuples.Select(e => new {
        IMPORT_TIME = e.Item1,
        CREATOR_ID = e.Item2,
        CREATOR_NAME = e.Item3,
        COUNT = e.Item4,
    });
    string json = Newtonsoft.Json.JsonConvert.SerializeObject(anonymities);
    return json;
}

局限 (一)

以下代码中,a.XXX 的类型为 stringb.YYY 的类型为 int
如果是 SQL Server 数据库,可能就没问题了。
但 Oracle 下执行 query.ToArray() 时总是报错。
总之,2015-05-12 在编写 "Visit System - Send Short Message for Hearing Screening" 时,需要基于不同类型的 a.XXXb.YYY 关联两个表,结果找不到 Entity Framework 的解决方案。Entity Framework 这么弱? 2015-11-13 在编写图书馆管理系统时遇到同样的问题,仍未找到解决方案,只好修改数据库将两个关联列的类型改为相同的数据类型。

var query =
    from a in db.TABLE_A
    join b in db.TABLE_B
    on a.XXX equals SqlFunctions.StringConvert((double?)b.YYY)
    select Tuple.Create(a, b);
var array = query.ToArray();