EF 剥坑

Posted EchoSong

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 琢磨下自己的代码

以上是关于EF 剥坑的主要内容,如果未能解决你的问题,请参考以下文章

EF6 自定义迁移表名

EF 开始的片段时有问题 具有潜在运行时冲突

EF Core 基础知识

.NET Entity Framework(EF)使用SqlQuery直接操作SQL查询语句或者执行过程

ASP.NET MVC4.0+EF+LINQ+bui+网站+角色权限管理系统

Shell编程入门