【EF】Entity Framework使用
一、EF框架之三种模式
Entity Framework是ORMapping的一种具体实现,那ORMapping又是什么呢?
ORM--ObjectRelation Mapping,即对象关系映射框架/数据持久化框架,是根据实体对象操作数据表中数据的一种面向对象的操作框架。
其实Entity Framework的底层也是调用Ado.Net,它是更高层次的封装。作为数据访问的技术,EntityFramework的设计有高扩展性,这一点可体现在其映射定义的灵活性。
简单地说,使用Entity Framework可以充分地定义与数据表映射的实体,这个实体可以直接用于业务逻辑层或作为服务的数据契约。
使用EF后,可以将实体类的设计工作完全放在EDM(实体数据模型)的设计过程中,而不需要手工写那些大同小异的代码,令人欣喜的是这个实体模型可以在运行时修改并生效,做到一改全改。
我们开发时也不用再频繁地与数据库打交道,我们操作实体模型的同时EF框架自动完成了对数据库的操作。
对于一种新了解的技术,了解宏观是必须的,但是要想尽快熟悉还是要实践一下的,我们知道网络上特别流行Codefist,下面就来说一说EF框架划分的模式:
- DataBase First(数据库优先)
- Model First(模型优先)
- CodeFirst(代码优先)
当然,如果把Code First模式的两种具体方式独立出来,那就是四种了。
1、DataBase First 传统的表驱动方式创建EDM,然后通过EDM生成模型和数据层代码。除生成实体模型和自跟踪实现模型,还支持生成轻型DbContext。在设计器中逆向生成Model,并有Model自动生成所有的类。
2、Model First 先创建EDM模型,再生成DDL数据库脚本和模型和数据层代码。除生成实体模型和自跟踪实现模型,支持生成轻型DbContext。在设计器中创建Model,并用Model生成数据库,所有的类由Model自动生成。
3、Code First(New DataBase) :在代码中定义类和映射关系并通过model生成数据库,使用迁移技术更新数据库。
4、Code First(Existing DataBase):在代码中定义类和映射关系,给逆向工程提供工具。
虽然Code First灵活,但是需手动创建POCO模型,数据层DbContext及映射关系,通过Database.SetInitializer生成数据库,这种方式较灵活,但是代码工作较多。
二、EF三种编程方式的区别
- datebase first就是代表数据库优先,那么前提就是先创建数据库和表。
- model first就是代表model优先,那么前提也就是先创建model,然后根据model自动建立数据库和表。
这两EF的编程方式在使用的过程中的区别为:
1、添加新建项->添加ADO.NET实体数据模型的时候,database first选择的是从数据库生成。而Model first选择的是空模型生成。

数据表的主键、外键,提前在DB设计中设置好。

并且在数据结构发生变化的时候,database first编程方式中是选择从数据库更新模型,model first选择的是从模型生成数据库。

modelFirst模式,若代码已经生成好了,切换到另一台电脑上执行时,尚未有数据库。
则在sql文件中右键:执行,则会自动创建数据表【不过首先在db中手动建一个数据库】。
注:只有第一次才能这样操作,不然执行sql会将原表中的数据删除掉(drop table),更新表结构时应该自己写sql更新

- code first就不需要创建一个ADO.NET实体模型的过程,直接在model里面写实体类和dbcontext上下文类。
在Code-First中,默认生成的数据库表的名称为类型的复数形式,如Model名为“Player”,默认生成的数据库表名为“Players”。很多情况下我们并不想生成的数据库表名为复数形式,如何来控制呢?
在public class DBContext : DbContext重写以下方法(去除复数的约束)
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
三、EF三种编程方式实践
1、Database First
Entity Framework4.1之前EF支持“Database First”和“Model First”编程方式,从EF4.1开始EF开始支持支持“Code First”编程方式,今天简单看一下EF三种编程方式。
开始介绍这三种EF操作方式之前,首先在Visual Studio 中建立一个数据库连接,这里我们以“EFDemo”数据库为例:
你可以使用EF设计工具根据数据库生成数据数据类,你可以使用Visual Studio模型设计器修改这些模型之间对应关系。
首先创建一个控制台应用程序,然后右键添加新建项,选择“ADO.NET Entity Data Model”,名称输入EFDemoDB:接着选择从数据库生成:下一步选择数据库连接,

创建完模型之后。你会发现Visual Studio自动为你生成了“Class、“Student”两个实体类和一个“EFDemoDB”数据库上下文操作类:

2、Model First
此种方式,当需要增加表、更新表(增加字段)的时候
即更新模型(EF里model生成步驟)
- 在edmx文件中 添加相应的表(实体)和字段(标量属性),记得添加注释【将显示在代码的Model注释上,sql文件里面不会有】,导航属性不用手动添加。
注意,属性中,实体集名称(自己定义)才是表的名字;

- 要添加表关系映射,在edmx空白处右键,选择新建=》关联,在弹出框里选择对应关系(多重性就是一对多什么的,关联是选择与哪个表进行关联)【导航属性会自动添加上】
注意:源是主表,目标是附表;
若 主键字段不是 用做两表匹配的字段,则需要设置一对多,若主键字段是用做两表匹配的字段,则可以不设置为一对多。
属性-》引用约束中 设置两个表相等的字段

- 在右建點擊edmx裡的模型,選擇從模型生成數據庫,即更新sql文件
- 右键Model1.Context.tt,然后点击运行自定义工具; 或者手动 修改tt文件里面的对应表的属性
- 編譯生成OK
5.再执行相應的sql腳本【提前建好 或者采用生成的SQL文件里的】,添加相應的表或字段
3、Code First
此种方式,不需要提前创建数据表,完全从代码开始。参考:Code First如何使用
四、EF加载方式
EF加载数据的方式,有预加载、延迟加载、显式加载、按需加载。不同的加载方式都有不同的适用情况,不能说哪种方式好哪种方式不好。但有一点是需要遵循的,那就是如何提高数据加载的效率。
1、延迟加载又叫惰性加载(Lazy Loading):即在需要或者使用的时候加载数据。默认情况下,EF会使用延迟加载方式加载数据,即数据库上下文的属性:Configuration.LazyLoadingEnabled = true;
eg:var customers = from c in dbcontext.Customer select c;
2、预加载:如果你想让所有数据一次性全部加载到内存中,那么你需要使用.Include(Entity)方法 。.Include(Entity)方法允许级联使用,你可以预先加载具有多层级结构的数据。
eg:var q = from t in dbcontext.Customer.Include("Order") select t;
比较两种加载方式
预加载:
• 减少数据访问的延迟,在一次数据库的访问中返回所有的数据。不过缺点是,那就是如果数据量较大,一次性将所有数据载入内存往往并不是最明智的选择
• 减少与数据库的交互次数
延迟加载:
• 非常宽容,因为只在需要的时候加载数据,不需要预先计划
• 可能会因为数据访问的延迟而降低性能,考虑到每访问父实体的子实体时,就需要访问数据库。
3、显式加载和延迟加载非常类似,不同的是显式加载要手动关闭EF的延迟加载属性,通过代码ctx.Configuration.LazyLoadingEnabled = false;来完成。
dbcontext.Configuration.LazyLoadingEnabled = false;
#region 显式加载:查询部分列数据,前提关闭 懒加载
//查询表中部分列的数据
var items = from c in dbcontext.Customer
select c;
foreach (var item in items)
{
//条件判断,只加载满足条件的数据,减少访问数据库的次数
if (item.Id < )
{
dbcontext.Entry(item).Collection(c => c.Order).Load();
Console.WriteLine(item.CusName);
}
4、按需加载
其实EF并不存在按需加载的概念,但是这种方式很值得说一说,在加载数据的时候并不是需要所有的属性值,可能只需要一个Id,Name值。
所以我们可以对要查询的实体进行一下筛选,只加载自己需要的某些列,避免加载大量的垃圾数据。在这里按需加载的概念只是加载需要的列
#region 按需加载:查询部分列数据
//查询表中部分列的数据
var items = from c in dbcontext.Customer
where c.Id <
select new { Id = c.Id, CName = c.CusName, OrderCount = c.Order.Count() };
foreach (var item in items)
{
Console.WriteLine(item.CName);
}
#endregion
其他参考
【EF】Entity Framework使用的更多相关文章
- EF(Entity Framework)多对多关系下用LINQ实现"NOT IN"查询
这是今天在实际开发中遇到的一个问题,需求是查询未分类的博文列表(未加入任何分类的博文),之前是通过存储过程实现的,今天用EF实现了,在这篇博文中记录一下. 博文的实体类BlogPost是这样定义的: ...
- [转载]灵动思绪EF(Entity FrameWork)
很久之前就想写这篇文章了,但是由于种种原因,没有将自己学习的EF知识整理成一片文章.今天我就用CodeFirst和ModelFirst两种方式的简单案例将自己学习的EF知识做个总结. 在讲解EF之前, ...
- EF(Entity Framework)通用DBHelper通用类,增删改查以及列表
其中 通用类名:DBhelper 实体类:UserInfo 1 //新增 2 DBHelper<UserInfo> dbhelper = new DBHelper<UserInfo& ...
- EF ( Entity Framework) 操作ArcCataLog 生成的(Sql Server)空间数据库
因为项目需求,现在需要利用EF 操作由Arccatalog生成的sql server空间数据库..在此之前,一直没有接触过空间数据库,在操作空间数据库时 绕了许多弯... 因此写一篇随笔做一个总结. ...
- EF Entity Framework Core DBContext中文文档
Add(Object) 以添加状态开始跟踪给定的实体和任何其他尚未被跟踪的可访问实体,以便在调用SaveChanges()时将它们插入数据库.使用State设置单个实体的状态. Add<TEnt ...
- [EF] - Entity Framework 6处理User Defined Function(UDF SQL Server)
随着EF5的发布,新增了对数据库(SQL Server) UDF的支持,具体可以看以下的连接:https://msdn.microsoft.com/en-us/data/hh859577.aspx,新 ...
- EF(Entity Framework)发生错误”正在创建模型,此时不可使用上下文“的解决办法。 正在创建模型,此时不可使用上下文。如果在 OnModelCreating 方法内使用上下文或如果多个线程同时访问同一上下文实例,可能引发此异常。请注意不保证 DbContext 的实例成员和相关类是线程安全的。 临时解决了这个问题,在Context的构造函数中,禁用了自动初始化:
解决方案: 禁止上下创建. 修改.删除,默认为true public DataDbContext() : base("name=DataDbContext") { this.Da ...
- Entity FrameWork(实体框架)是以ADO.NET Entity FrameWork ,简称为EF
Entity FrameWork(实体框架)是以ADO.NET Entity FrameWork ,简称为EF Entity FrameWork的特点 1.支持多种数据库(MSSQL.Oracle.M ...
- 2、ASP.NET MVC入门到精通——Entity Framework入门
实体框架(Entity Framework)简介 简称EF 与ADO.NET关系 ADO.NET Entity Framework 是微软以 ADO.NET 为基础所发展出来的对象关系对应 (O/R ...
- [Programming Entity Framework] 第3章 查询实体数据模型(EDM)(一)
http://www.cnblogs.com/sansi/archive/2012/10/18/2729337.html Programming Entity Framework 第二版翻译索引 你可 ...
随机推荐
- 树莓派raspberrypi系统安装docker以及编译nginx和php镜像
前言 在树莓派中搭建php环境,按正常流程一般是直接在系统中apt-get install相关的软件,不过如果某天我想无缝迁移到另一个地方,就又得在重新安装一次环境.所以为了方便,就直接在树莓派中使用 ...
- 状态机的Verilog写法
“硬件设计很讲究并行设计思想,虽然用Verilog描述的电路大都是并行实现的,但是对于实际的工程应用,往往需要让硬件来实现一些具有一定顺序的工作,这就要用到状态机思想.什么是状态机呢?简单的说,就是通 ...
- swagger 报错:illegal defaultValue null for param type integer
swagger(版本2.9.2) 刷新报错,错误信息如下图: 问题原因: 根据上面这句报错信息,点进去AbstractSerializableParameter.java:412可以看到 源码, @J ...
- 基于MBT的自动化测试工具——GraphWalker介绍和实际使用
GraphWalker是一个开源的基于模型的自动化测试工具,它可以用来通过图形测试模型来自动生成测试用例. 本文主要描述了使用yed画出FSM, EFSM模型图(常见的流程图),然后使用GraphWa ...
- AI人脸识别SDK接入 — 参数优化篇(虹软)
引言 使用了虹软公司免费的人脸识别算法,感觉还是很不错的,当然,如果是初次接触的话会对一些接口的参数有些疑问的.这里分享一下我对一些参数的验证结果(这里以windows版本为例,linux.andro ...
- QT生成的exe在其他电脑打开
首先说一下我的开发的平台:vs2017+QT5.9 我们首先先用release版本来编译一下程序,然后我们得到了一个exe程序但是这个程序是不能脱离你的平台,甚至是不能脱离你所在的文件夹,这是因为它需 ...
- 文件操作之stat()函数
作用: 返回一个文件的详细信息 头文件: #include <sys/types.h> #include <sys/stat.h> #include <unistd.h& ...
- 根据byte数组,生成文件
/** * 根据byte数组,生成文件 * filePath 文件路径 * fileName 文件名称(需要带后缀,如*.jpg.*.java.*.xml) */ public static void ...
- Java精通并发-锁升级与偏向锁深入解析
对于synchronized关键字,我们在实际使用时可能经常听说用它是一个非常重的操作,其实这个“重”是要针对JDK的版本来说的,如今JDK已经到了12版本了,其实对这个关键字一直是存在偏见的,它底层 ...
- Java volatile关键字实现原理
场景引入 可见性问题 先来看一张图: 上面的图,是简化版的Java内存模型,一个线程有自己的工作内存,同时还有一个共享的主内存. 线程1和线程2读取数据data时,先从主内存里加载data变量的值到工 ...