EF6

  • ORM对象关系映射
    • 原生
    • ORM框架
    • 各ORM框架介绍
  • EF6的三种映射方式
    • 三种映射方式
    • 映射方式
    • 映射策略
  • 复杂查询&执行Sql
    • EF各种复杂的查询:
    • EF6 SQL查询
    • EF6-Context
  • EF状态跟踪
  • EF中的缓存提升效率:
  • EF上下文生命周期/事务
  • EF延迟
  • 导航属性
  • 主键自增
  • 事务
  • ORM-EF整合:
    • 项目初始结构
    • 分层架构
    • 带接口层

ORM对象关系映射

 要介绍ORM框架,首先需要说一下原生框架。

原生


进程交互靠的是网络协议
ado.net 操作数据库(sqlcommand 、sqlconnection 、adapter 、datareader )
操作数据库—数据库只认识Sql语句

但是原生操作不方便的地方:

  1. 写起来比较麻烦。
  2. 开发者得知道sql。
  3. 不同的表写不同的sql就会有重复代码。
  4. 开发效率就低一些-但性能最好。

ORM框架


ORM是一个封装,是一个代理,可以把数据库“搬”到程序中,要操作数据库,可以直接通过操作ORM框架完成对数据库的操作;
ORM-底层—ADO.NET;进一步的封装了,可以通过映射以后,通过对实体的操作,达到数据库中数据的操作(本质是通过类来反射生成SQL语句);

  1. 生成Sql语句—大量的反射;
  2. 性能不好—可以通过缓存来解决
  3. Sql语句是由程序生成,相对来说比较僵化,没有我们自己写的精炼;
  4. 开发便捷,不需要去了解Sql,降低学习成本;
  5. 思想的进步—操作类(对象),以面向对象的思想去操作数据库

各ORM框架介绍

  1. EF6:比较重,可以支持多种数据库,可以支持数据库的迁移;和VS配合的好;已经非常成熟了;
  2. NHibernate:比较重;
  3. Dapper:轻量级—宇宙第一性能之王;
  4. IBatis.Net
  5. LinqToSql:只支持SqlServer,现在已经不在维护了;
  6. Sql sugar
    现在使用的大部分ORM—基本上都是可以直接支持Sql语句;

EF6的三种映射方式

三种映射方式

  1. DbFirst: -----数据库先行,通过数据库来映射不同的实体(对应数据库中不同的表),视图+存储过程+函数;
  2. CodeFirst: -----代码先行,直接写业务逻辑,通过业务逻辑实体去生成数据库;
  3. CodeFirstFromDb: -----数据库已经存在,还是代码先行,数据存在就不用生成数据库;
  4. ModuleFirst:相当于一个设计工具,做了数据库的事儿;

映射方式

  1. 特性映射 Table(“数据库表名称”) , [Column(“Name”)]
  2. modelBuilder.Entity<类名称>()
    .ToTable(表名称) .Property(c => c.属性名称)
    .HasColumnName(数据库字段名称);
  public class SysLogMapping : EntityTypeConfiguration<SysLogShow>{ public SysLogMapping(){this.ToTable("SysLog");}}

映射策略

new CreateDatabaseIfNotExists<CodeFirstContext>();//默认不存在就创建 new DropCreateDatabaseAlways<CodeFirstContext>();//每次都删除重建
new DropCreateDatabaseIfModelChanges<CodeFirstContext>();//数据库已经存在,还是代码先行,数据存在就不用生成数据库;
Database.SetInitializer<CodeFirstContext>(new DropCreateDatabaseIfModelChanges<CodeFirstContext>());

复杂查询&执行Sql

EF各种复杂的查询:

  • In查询:Contains关键字
  • 排序/投影/分页:OrderBy/Select/Skip(3).Take(5)
  • 多重循环嵌套:Where().Where()
  • 关联查询:join/ DefaultIfEmpty()
var list = (from u in dbContext.SysUsersjoin c in dbContext.Companies on u.CompanyId equals c.Id //条件不能写等号,要使用equals关键字where new int[] { 1, 2, 3, 4, 6, 7, 10 }.Contains(u.Id)select new{Name = u.Name,Pwd = u.Password,CompanyName = c.Name}).OrderBy(u=>u.CompanyName).Skip(3).Take(5);foreach (var user in list){Console.WriteLine("{0} {1}", user.Name, user.Pwd);}

EF6 SQL查询

那都是生成Sql语句,如果我自己来一条Sql语句呢?咋玩?

dbContext.Database.SqlQuery<SysUser>(sql, parameter);

那我如果Sql语句直接执行,如何保证数据库的一致性?
事务执行:

dbContext.Database.BeginTransaction()
trans.Commit()

EF6-Context

SaveChanges是以context为维度,如果监听到任何数据的变化;
然后会一次性的保存到数据库去,而且会开启事务!
新换的环境DBContext运行监视时提示找不到MigrationHistory
把下面这句放到DBContext中即可

Database.SetInitializer<ZhaoxiDbContext>(null);

//设置要用于给定上下文类型的数据库初始值设定项。当给定的 System.Data.Entity.DbContext 类型首次用于访问数据库时调用数据库初始值设定项。设置为NUll禁止初始化

EF状态跟踪

  1. Context.Entry(userNew).State :获取实体的状态
  2. Detached: 和Context 完全没有任何关系,不受Context跟踪
  3. Unchanged:受Context跟踪,但是没有做任何操作
  4. Added:受Context 跟踪,SaveChange就添加到数据库
  5. Deleted:受Context跟踪,SaveChange就删除数据库数据
  6. Modified:受Context跟踪,SaveChange就修改数据库
    那如果是这样的话,岂不是每一次更新都需要从数据库里查询一次?
    老师之前在工作的时候,大部分情况下是这样,先查询,再修改,为了保证实体受Context监管!
    也可以有其他的方案:Context.实体名称.Attach() 接受Context监管!

那如何更新全部字段0呢?

context.Entry<User>(user).State = EntityState.Modified;//全字段更新

那如何选择性的更新字段呢?

context.Entry<User>(user5).Property("Name").IsModified = true;//指定某字段被改过

EF中的缓存提升效率:

Find查询默认是优先从内存中去查找,如果内存没有,就再去数据库查找,可以提高性能;
建议:大家尽量的使用Find查询
AsNoTracking() 方法会直接切断Context跟踪;可以提高性能!

EF上下文生命周期/事务

Context事务:
多种数据修改,执行SaveChange,开启事务保存,任何一个数据的操作执行失败,事务直接回退!
那每个数据操作都去来个context实例?

  1. 内存消耗大,没法缓存。
  2. 多context实例 join 不行,因为上下文环境不一样;除非把数据都查到内存,再去linq。
  3. 多context的事务执行起来不要另外的操作!
    老师建议:DbContext是个上下文环境,里面内置对象跟踪,会开启链接(就等于一个数据库链接);一次请求,最好是一个context;多个请求 /多线程最好是多个实例;用完尽快释放;

EF延迟

EF延迟查询:
A context.SysUser.where()…并没有去查询!
B 只有在使用数据的时候,才去数据库查询数据!可以叠加多次查询条件,一次提交给数据库;可以按需获取数据;
a 只有在使用完数据时候,才会关闭连接
b 只能在Context作用域内有效

LinqToObject和LinqToSql的区别;
LinqToObject:返回的是IEnumerable类型,数据其实已经在内存里,有个迭代器的实现,参数用的是委托

LinqToSql:返回的IQueryable类型,数据在数据库里面,这个list里面有表达式目录树—返回值类型–IQueryProvider(查询的支持工具,sqlserver语句的生成),其实userList只是一个包装对象,里面有表达式目录树,有结果类型,有解析工具,还有上下文,真需要数据的时候才去解析sql,执行sql,拿到数据的;

导航属性

主外键表,主表有个子表的集合,子表有一个主表的实例----导航属性

1 默认情况下,导航属性是延迟查询;virtaul+默认配置
2 关闭延迟加载,子表数据就没了 dbContext.Configuration.LazyLoadingEnabled = false
3 预先加载 Include 查询主表时就把子表数据一次性查出来 dbContext.Set().Include(“Users”)
4 关闭延迟查询后,如果需要子表数据,可以显示加载
dbContext.Entry(company).Collection(c => c.Users).Load();
dbContext.Entry(company).Reference(c => c.Users).Load();

主键自增

数据插入:A表–B表(包含A的ID)—A表的ID是自增的
一次SaveChange ,如果是主外键关系,可以自动使用自增id;
如果不是主外键关系,就无法使用这个自增的ID
那直接分两次SaveChange;会有事务问题;
通过事务可以解决:TransactionScope trans = new TransactionScope(); trans.Complete()

事务

SaveChange可以完成单个context实例的事务
TransactionScope完成一个context的多次SaveChange,
只有在TransactionScope. Complete()以后SaveChange才会生效
TransactionScope完成不同context实例的事务

ORM-EF整合:

项目初始结构


缺点:不太好应对项目后续的发展。
所有内容都在一起,任何一个环节修改都必须重新发布/测试,高耦合,成本高!

分层架构


水平分:把一个操作的执行流程给分成多个类库

  1. 软件可以解耦
  2. 便于分工
  3. 便于维护(功能知道出处)
  4. 组件重用
  5. 便于组件替换
  6. 便于功能扩展
  7. 能应对需求的变化

带接口层

18.NET高级开发之ORM-EF6相关推荐

  1. Android高级开发之【RxJava】详解(附项目源码)

    文章大纲 一.什么是RxJava 二.为什么要用RxJava 三.RxJava使用详解 四.项目源码下载 一.什么是RxJava Rx(Reactive Extensions)是一个库,用来处理事件和 ...

  2. Android开发之TextView高级应用

    Android开发之TextView高级应用 我们平时使用TextView往往让它作为一个显示文字的容器,但TextView的功能并不局限于此.以下就和大家分享一下TextView的一些使用技巧. A ...

  3. 电影天堂APP项目开发之Python爬虫篇,共18课时/5时33分

    电影天堂APP项目开发之Python爬虫篇,共18课时/5时33分,是电影天堂APP项目开发课程的第一篇章,讲解使用requests和bs4库,爬取和解析电影天堂网站数据,并讲数据保存到SQLite数 ...

  4. 18. 【移动Web开发之rem适配布局】

    文章目录 [移动Web开发之rem适配布局]前端小抄(18) 一.rem单位 1.1 rem 单位 二.媒体查询 2.1 什么是媒体查询 2.2 语法规范 2.2.1 mediatype 查询类型 2 ...

  5. 微信公众号开发之 “`高级接口`” 总结

    微信公众号开发之 "高级接口" 总结 代码如下: <?php// $weixin = new class_weixin("", "") ...

  6. 苹果开发之Cocoa编程(原书第4版)

    <苹果开发之Cocoa编程(原书第4版)> 基本信息 原书名:Cocoa Programming for Mac OS X: Fourth Edition 作者: (美)希莱加斯(Hill ...

  7. Swift Web 开发之 Vapor - 入门(一)

    简介 Vapor 是一个基于纯 Swift 构建出的 Web 开发框架,目前可以运行在 macOS 和 Ubuntu ,用于构建出漂亮易用的网站或者 API 服务. 官方称是用的最多的 Swift w ...

  8. python开发之Django(二)

    python开发之Django(二) 一.ORM 1. ORM基础 2. Django ORM语法 2.1 表(模型)的创建: 2.2 表的操作 2.2.1 增删改查 2.2.2 对象查询,单表条件查 ...

  9. 3G应用开发之Android 传智播客 基础知识总结

    3G应用开发之Android Android应用开发之3G  3G应用开发之Android 3G应用开发之Android 应用开发之 讲师: 讲师:黎活明 北京传智 播客教育 www.itcast.c ...

最新文章

  1. BERT的成功是否依赖于虚假相关的统计线索?
  2. 各种资源思科、gns3……
  3. 滚动的组件_我们成功的一个组件 KRW滚动体
  4. 电商泛滥的时代,我们的出路在哪里?
  5. php中ip授权系统,PHP授权验证系统(域名+IP双重验证一键更新授权系统)
  6. java iterator如何倒序输出
  7. 【每日一题】7月10日精讲—矩阵取数游戏
  8. cms安装教程Linux,DoraCMS安装教程(linux)
  9. 导航器 Navigator
  10. Oralce 时间TIMESTAMP的比较
  11. 关于预编译和Stdafx.h的若干问题
  12. 记录一次es head测试使用说明
  13. 2022 SpringBoot/SSM的药品售货机平台 H5药品购买商城
  14. ShuffleNet 算法的介绍
  15. python微信投票该用户被锁定、恢复时间_微信登录多久恢复正常
  16. 企业税务负面信息综合查询
  17. 手游自动化测试框架实现原理
  18. 最新苹果手机备份同步工具 iMazing2.16.4官方免费下载
  19. swap未禁用导致的k8s NotReady
  20. Java 初学者做的第一个微信小程序--关于Java基础

热门文章

  1. 云队友丨中国互联网反垄断简史
  2. 明瞳智控四月再升级,视图终端上云更便捷
  3. 腾讯云对象存储 COS 荣获对象存储领导力奖!!!
  4. 我们该如何高效的学习
  5. webbrowser屏蔽网页弹出框和脚本错误提示框
  6. excel matlab日期,Excel日期格式在matlab中的转换
  7. 特斯拉新能源汽车遍地开花 汽车品牌纷纷建立电动化品牌战略
  8. 支付宝/小钱袋H5支付通道
  9. 电脑本地连接图标不见 怎样找到恢复处理无法创建宽带连接(转)
  10. 恒生电子实习记录-2