zoukankan      html  css  js  c++  java
  • EF 剥坑

    1、简单 count 会生成不必要的嵌套

    var xs = (from x in dbContext.db_API_Operationallog where x.id<1  select 1 ).Count();
    
    结果:
    
    SELECT 
    [GroupBy1].[A1] AS [C1]
    FROM ( SELECT 
        COUNT(1) AS [A1]
        FROM [dbo].[db_API_Operationallog] AS [Extent1]
        WHERE [Extent1].[id] < 1
    )  AS [GroupBy1]
    

    2、查询某些列的时候会整个模型查询

        context.db_API_Operationallog.FirstOrDefault(p => p.Id == postId).Hits;
        或者:
        context.db_API_Operationallog.Find(postId).Hits;
    

    会把整个post表数据都查出然后再内存里面找了hits这个列

    优化:

        context.db_API_Operationallog.Where(p => p.Id == postId).Select(p => p.Hits).FirstOrDefault();
    

    3、不要轻易的把数据全部加载到内存

    有时候一个不小心在查询的sql build 里面加了个tolist(), toArray()等,这种真正的执行了查询,这样在开发环境往往表的数据比较少,程序运行比较快,但是一到线上环境数据量比较大的情况下就会出现内存爆满的问题,这个问题相对来说比较隐蔽,所以开发的时候一定要小心。

    4、IQueryable, IEnumerable

    IEnumerable 执行的where 先是走内存,在走内存查询

        public IEnumerable<db_API_Operationallog> GetAllPost()
        {
                return context.Post;
        }
    
        int id = 2000;
        var log = GetAllPost().Where(s => s.id <id).ToList();
    

    Sql Server Profiler 抓到的信息

     SELECT 
    [Extent1].[id] AS [id], 
    [Extent1].[uid] AS [uid], 
    [Extent1].[types] AS [types], 
    [Extent1].[events] AS [events], 
    [Extent1].[more] AS [more], 
    [Extent1].[money] AS [money], 
    [Extent1].[lastmoney] AS [lastmoney], 
    [Extent1].[nowmoney] AS [nowmoney], 
    [Extent1].[bak] AS [bak], 
    [Extent1].[times] AS [times]
    FROM [dbo].[db_API_Operationallog] AS [Extent1]
    

    把上面的 IEnumerable 换成 IQueryable

    exec sp_executesql N'SELECT 
    [Extent1].[id] AS [id], 
    [Extent1].[uid] AS [uid], 
    [Extent1].[types] AS [types], 
    [Extent1].[events] AS [events], 
    [Extent1].[more] AS [more], 
    [Extent1].[money] AS [money], 
    [Extent1].[lastmoney] AS [lastmoney], 
    [Extent1].[nowmoney] AS [nowmoney], 
    [Extent1].[bak] AS [bak], 
    [Extent1].[times] AS [times]
    FROM [dbo].[db_API_Operationallog] AS [Extent1]
    WHERE [Extent1].[id] < @p__linq__0',N'@p__linq__0 int',@p__linq__0=2000
    

    这个坑是比较同样也是比较隐蔽的注意下

    5、使用 NoTracking 降低 状态开销

      dbContext.db_API_Operationallog.Where(s => s.id < id).AsNoTracking().ToList();
    

    总结

    平时写EF的时候一定要把脚步停下了 多使用 Sql Server Profiler 琢磨下自己的代码

  • 相关阅读:
    Filter过滤器
    jsp-JSTL表达式
    jsp-EL表达式
    JSP概述
    servlet编码问题
    微信开放平台-踩坑1
    Supervisor的安装以及使用
    laravel-mix的安装
    Laravel框架中打印sql
    Laravel 5.7 使用 PHP artisan migrate 的问题
  • 原文地址:https://www.cnblogs.com/echosong/p/5519772.html
Copyright © 2011-2022 走看看