博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Entity Framework 使用注意:Where查询条件中用到的关联实体不需要Include
阅读量:7200 次
发布时间:2019-06-29

本文共 2380 字,大约阅读时间需要 7 分钟。

在Entity Framework中,如果实体A关联了实体B,你想在加载实体A的同时加载实体B。通常做法是在LINQ查询中使用Include()。但是,如果你在查询条件中用到了实体B,EF会自动加载实体B,这时Include不仅是多余的,而且还会增加额外的LEFT OUTER JOIN查询,影响性能。 

请看我们在开发中遭遇这个问题时的一段代码:

//For q.cnblogs.compublic class QuestionService {    private IRepository
_questionRepository; public QuestionService(IUnitOfWork unitOfWork) : base(unitOfWork) { _questionRepository = new Repository
(unitOfWork); } public List
GetUnsolvedQuestions(int pageIndex, int pageSize) { return _questionRepository.Entities .Include(q => q.User) .Where(q => q.IsActive && q.User.IsActive) .Skip((pageIndex - 1) * pageSize) .Take(pageSize) .ToList(); }}public class QuestionItem{ public int Id { get;set; } public string Title { get; set; } public bool IsActive { get; set; } public int UserId { get; set; } public User User { get; set; }}public class User{ public int UserId { get; set; } public bool IsActive {get;set;}}

在上面的代码中,我们想在GetActiveQuestions()返回List<QuestionItem>时,QuestionItem中要包含User信息,所以在LINQ查询使用了.Include(q => q.User)。

(特别要注意的是:这里把q.User.IsActive作为查询条件之一)

然后我们用SQL Server Profiler发现,Entity Framework生成了如下的SQL语句:

SELECT TOP (25) [Filter1].[Id] AS [Id], [Filter1].[Title] AS [Title],[Filter1].[UserId] AS [UserId], [Filter1].[UserId1] AS [UserId1], [Filter1].[IsActive1] AS [IsActive], [Filter1].[UserId2] AS [UserId1],[Filter1].[IsActive2] AS [IsActive1]FROM ( SELECT [Extent1].[Id] AS [Id], [Extent1].[Title] AS [Title], [Extent1].[UserId] AS [UserId1],[Extent1].[IsActive] AS [IsActive1],[Extent3].[UserID] AS [UserID2], [Extent3].[IsActive] AS [IsActive2], row_number() OVER (ORDER BY [Extent1].[QID] DESC) AS [row_number]    FROM   [dbo].[question_Item] AS [Extent1]    INNER JOIN [dbo].[Users] AS [Extent2] ON [Extent1].[UserID] = [Extent2].[UserID]    LEFT OUTER JOIN [dbo].[Users] AS [Extent3] ON [Extent1].[UserID] = [Extent3].[UserID]    WHERE ([Extent1].[IsActive] = 1) AND ([Extent2].[IsActive] = 1) )  AS [Filter1]WHERE [Filter1].[row_number] > 0ORDER BY [Filter1].[Id] DESC

[dbo].[Users]表对应的就是User实体类,上面的SQL中[dbo].[Users]出现了两次JOIN,由于[Users]表数据量比较大,两次JOIN影响了执行计划,查询耗时增加。这显然是要避免的。

在与这个问题一阵激战之后,我们终于找到解决方法 —— 去掉Include,就这么简单!

从这个地方看,Entity Framework还是挺聪明的,但是由于不知道它的这个聪明之处,反而带来了问题。

所以,代码如人,要和她相处好,就要了解她的一切!

转载地址:http://fdzum.baihongyu.com/

你可能感兴趣的文章
OSChina 周三乱弹 ——我们职业更好的名字:爱码士
查看>>
左边的项目管理器不见了
查看>>
android 获取唯一标识
查看>>
HTML5 - Server-Sent Events
查看>>
为MySQL授权
查看>>
用 Octave 对音频文件进行基本数学的信号处理
查看>>
看视频是好的学习方法
查看>>
Get last order or items of customer in magento
查看>>
centos7安装redis3.2.1
查看>>
聚合数据Android SDK 天气查询演示示例
查看>>
java冒泡排序法
查看>>
tomcat启停脚本高级版
查看>>
【Microsoft Edge中新的F12开发者工具】
查看>>
java基础第五天
查看>>
提取Fiddler抓包软件的抓到的数据
查看>>
Vsftpd 安全
查看>>
Android开发之下载服务器上的一张图片到本地java代码实现HttpURLConnection
查看>>
安全运维之:网络性能评估工具Iperf
查看>>
sort 排序
查看>>
Java8初体验(二)Stream语法 3
查看>>