zoukankan      html  css  js  c++  java
  • EF6

    一、O/RM对象关系映射
     
    ORM是一个封装,是一个代理,可以直接通过操作ORM框架完成对数据库的操作;
     
    数据库只认识sql语句;
    ORM-底层—ADO.NET的进一步的封装,可以通过映射以后,对实体的操作,达到数据库中数据的操作;
     
    缺点:
    1.生成Sql语句---大量的反射;
    2.性能不好---可以通过缓存来解决
    3.Sql语句是由程序生成,相对来说比较僵化,没有我们自己写的精炼;
     
    优点:
    4.开发便捷,不需要去了解Sql,降低学习成本;
    5.思想的进步---操作类(对象),以面向对象的思想去操作数据库
     
    EF6                    比较重,可以支持多种数据库,可以支持数据库的迁移;和VS配合的好;已经非常成熟了;
    NHibernate       比较重;    
    Dapper              轻量级---宇宙第一性能之王;    
    IBatis.Net               
    LinqToSql          只支持SqlServer,现在已经不在维护了;
    Sql sugar       
    现在使用的大部分ORM—基本上都是可以直接支持Sql语句;
     
     
    DbFirst:                            -----数据库先行,通过数据库来映射不同的实体(对应数据库中不同的表),视图+存储过程+函数;
     
    CodeFirst:                        -----代码先行,直接写业务逻辑,通过业务逻辑实体去生成数据库;
    CodeFirstFromDb:          -----数据库已经存在,还是代码先行,数据存在就不用生成数据库;
     
    ModuleFirst:相当于一个设计工具,做了数据库的事儿
     
     
    二、EF6的三种映射方式
    1.  特性映射  Table(“数据库表名称”) , [Column("Name")]
    2. modelBuilder.Entity<类名称>()
            .ToTable(表名称) .Property(c => c.属性名称)
            .HasColumnName(数据库字段名称);
    3. 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>());
     
     
    EF6封装类库步骤:
    1.封装类库
    2.调用方引用
    3.引用EF相关包
    4.Copy配置文件
     
     
    SaveChanges是以context为维度,如果监听到任何数据的变化;
    然后会一次性的保存到数据库去,而且会开启事务!
     
     
    三、EF实现数据的CRUD
     
     
    四、复杂查询&执行Sql
     
    EF各种复杂的查询:
    In查询:Contains关键字
    排序/投影/分页:OrderBy/Select/Skip(3).Take(5)
    多重循环嵌套:Where().Where()
    关联查询:join/ DefaultIfEmpty()
     
     
    那都是生成Sql语句,如果我自己来一条Sql语句呢?咋玩?
    dbContext.Database.SqlQuery<SysUser>(sql, parameter)
    那我如果Sql语句直接执行,如何保证数据库的一致性?
    事务执行:dbContext.Database.BeginTransaction()
            trans.Commit()
     
     
     
    五、EF状态跟踪
     
    Context.Entry<User>(userNew).State :获取实体的状态
     
    Detached: 和Context 完全没有任何关系,不受Context跟踪
    Unchanged:受Context跟踪,但是没有做任何操作
    Added:受Context 跟踪,SaveChange就添加到数据库
    Deleted:受Context跟踪,SaveChange就删除数据库数据
    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跟踪;可以提高性能!
     
     
     
    六、Context生命周期解析
     
     
    Context事务:
    多种数据修改,执行SaveChange,开启事务保存,任何一个数据的操作执行失败,事务直接回退!
    那整个进程就直接Context实例?
    多线程能不能是一个实例呢
     
    那每个数据操作都去来个context实例?
    1 内存消耗大,没法缓存
    2 多context实例 join 不行,因为上下文环境不一样;除非把数据都查到内存,再去linq
    3 多context的事务执行起来不要另外的操作!
    私人建议:DbContext是个上下文环境,里面内置对象跟踪,会开启链接(就等于一个数据库链接);一次请求,最好是一个context;多个请求 /多线程最好是多个实例;用完尽快释放;
     
     
     
    七、延迟查询
     
    EF延迟查询:
    A   context.SysUser.where()…并没有去查询!
    B   只有在使用数据的时候,才去数据库查询数据!可以叠加多次查询条件,一次提交给数据库;可以按需获取数据;
    a 只有在使用完数据时候,才会关闭连接  
    b 只能在Context作用域内有效
     
     
    LinqToObject和LinqToSql的区别;
    LinqToObject:返回的是IEnumerable类型,数据其实已经在内存里,有个迭代器的实现,参数用的是委托
     
    LinqToSql:返回的IQueryable类型,数据在数据库里面,这个list里面有表达式目录树---返回值类型--IQueryProvider(查询的支持工具,sqlserver语句的生成),其实userList只是一个包装对象,里面有表达式目录树,有结果类型,有解析工具,还有上下文,真需要数据的时候才去解析sql,执行sql,拿到数据的;
     
     
    八、事务-多种事务
     
    主键自增
    数据插入: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实例的事务
     
     
    九、导航属性
     
    主外键表,主表有个子表的集合,子表有一个主表的实例----导航属性
     
    1 默认情况下,导航属性是延迟查询;virtaul+默认配置
    2 关闭延迟加载,子表数据就没了     dbContext.Configuration.LazyLoadingEnabled = false
    3 预先加载  Include 查询主表时就把子表数据一次性查出来    dbContext.Set<Company>().Include("Users")
    4 关闭延迟查询后,如果需要子表数据,可以显示加载
            dbContext.Entry<Company>(company).Collection(c => c.Users).Load();
            dbContext.Entry<Company>(company).Reference(c => c.Users).Load();
     
     
  • 相关阅读:
    我为能准时下班而做的准备,以及由此的收获,同时总结下不足
    用象棋的思维趣说IT人的职业发展和钱途
    简历上如果出现过于高大上的项目,反而过犹不及:再论如何通过项目引出技术
    用python的matplotlib和numpy库绘制股票K线均线的整合效果(含从网络接口爬取数据和验证交易策略代码)
    如果当前没有拿得出手的简历,也别慌,努力的话最多两年情况就能改变
    分析若干没面试机会和没体现实力的简历
    IT人为了自己父母和家庭,更得注意自己的身体和心理健康
    Spring Cloud系列文,Feign整合Ribbon和Hysrix
    以互联网公司的经验告诉大家,架构师究竟比高级开发厉害在哪?
    博客园是个大金矿,管理员不挖掘有些可惜:给博客园提一些双赢的建议
  • 原文地址:https://www.cnblogs.com/hcy-zyy/p/14782752.html
Copyright © 2011-2022 走看看