zoukankan      html  css  js  c++  java
  • EF中执行sql语句

    EF原理

    EF 会自动把 Where()、OrderBy()、Select()等这些编译成“表达式树(Expression Tree)”,然后会把表达式树翻译成 SQL 语句去执行。(编译原理,AST)因此不是“把数据都取到内存中,然后使用集合的方法进行数据过滤”,因此性能不会低。但是如果这个操作不能被翻译成 SQL 语句,则或者报错,或者被放到内存中操作,性能就会非常低

    跟踪EF的查询Sql语句:

    DbContext 有一个 Database 属性,其中的 Log 属性,是 Action<String>委托类型,也就是可以指向一个 void A(string s)方法,其中的参数就是执行的 SQL 语句,每次 EF 执行 SQL 语句的时候都会执行 Log。因此就可以知道执行了什么 SQL。


    执行原始sql语句

    执行非查询语句,调用 DbContext 的 Database 属性的 ExecuteSqlCommand 方法,可以通过占位符的方式传递参数:

    更新语句

    ctx.Database.ExecuteSqlCommand("update T_Persons set Name={0},CreateDateTime=GetDate()","zjf");

    占位符的方式不是字符串拼接,经过观察生成的 SQL 语句,发现仍然是参数化查询,因此不会有 SQL 注入漏洞。

    查询语句:

    var q1 = ctx.Database.SqlQuery<Item1>("select Name,Count(*) Count from T_Persons where Id>{0} and CreateDateTime<={1} group by Name"

    返回值是 DbRawSqlQuery<T> 类型,也是实现了 IEnumerable 接口

    类似于 ExecuteScalar 的操作比较麻烦:

    int c = ctx.Database.SqlQuery<int>("select count(*) from T_Persons").SingleOrDefault();

    EF中的对象状态:

     Detached(游离态,脱离态)、Unchanged(未改变)、Added(新增)、Deleted(删除)、Modified(被修改)。

    转换图

    Add()、Remove()修改对象的状态。所有状态之间几乎都可以通过: Entry(p).State=xxx 的方式 进行强制状态转换

     EF 优化的一个技巧

    如果查询出来的对象 只是供显示使用,不会修改、删除后保存,那么可以使用AsNoTracking()来使得查询出来的对象是 Detached 状态,这样对对象的修改也还是 Detached状态,EF 不再跟踪这个对象状态的改变,能够提升性能。

    var p1 = ctx.Persons.Where(p => p.Name == "rupeng.com").FirstOrDefault();
    Console.WriteLine(ctx.Entry(p1).State);

    改成:

    var p1 = ctx.Persons.AsNoTracking().Where(p => p.Name == "rupeng.com").FirstOrDefault();
    Console.WriteLine(ctx.Entry(p1).State);

    因为 AsNoTracking()是 DbQuery 类(DbSet 的父类)的方法,所以要先在 DbSet 后调用AsNoTracking()。

  • 相关阅读:
    Simple DirectMedia Layer常用API总结
    [游戏复刻] Super Mario Brothers(1985. Famicom)
    [游戏复刻] 2048(2014. Android)
    图的结构以及寻路算法的c实现
    散列查找的C实现
    【游戏编程从0开始】一、基本结构
    C++中const关键字用法总结
    C标准库常用函数概要
    字符串表达式计算器的设计
    初探数据结构
  • 原文地址:https://www.cnblogs.com/lyfingchow/p/6576329.html
Copyright © 2011-2022 走看看