c#-使用实体框架进行简单请求的执行时间较长
作者:互联网
我有一个来自Entity Framework 6的怪异行为.我有一个简单的查询(一个简单的where和一个select),耗时30秒.
我使用Sql Profiler来查看执行了什么sql代码.我正在使用Where然后使用FirstOrDefault方法获取项目.然后,我尝试了另一个查询,我先执行了ToList(以获取数据),然后执行FirstOrDefault,它花费了不到1秒的时间.
Original code (takes 30s to be executed):
-----------------------------------------
id = Container.SocialNetworks.Where(a => a.SocialNetwork == EnumSocialNetwork.LinkedIn && a.Link == linkedinurl && a.User.TenantID == Container.TenantId).Select(i => i.UserID).FirstOrDefault();
From SQL Profiler :
-------------------
exec sp_executesql N'SELECT
[Limit1].[UserID] AS [UserID]
FROM ( SELECT TOP (1)
[Extent1].[UserID] AS [UserID]
FROM [dbo].[SocialNetworks] AS [Extent1]
INNER JOIN [dbo].[Users] AS [Extent2] ON [Extent1].[UserID] = [Extent2].[ID]
WHERE (0 = [Extent1].[SocialNetwork]) AND (([Extent1].[Link] = @p__linq__0) OR (([Extent1].[Link] IS NULL) AND (@p__linq__0 IS NULL))) AND ([Extent2].[TenantID] = @p__linq__1)
) AS [Limit1]',N'@p__linq__0 nvarchar(4000),@p__linq__1 int',@p__linq__0=N'linkedin.com/in/a-profile',@p__linq__1=5
After testing another solutions (takes less than 1s):
-----------------------------------------------------
id = Container.SocialNetworks.Where(a => a.SocialNetwork == EnumSocialNetwork.LinkedIn && a.Link == linkedinurl && a.User.TenantID == Container.TenantId).Select(i => i.UserID).ToList().FirstOrDefault();
From SQL Profiler:
------------------
exec sp_executesql N'SELECT
[Extent1].[UserID] AS [UserID]
FROM [dbo].[SocialNetworks] AS [Extent1]
INNER JOIN [dbo].[Users] AS [Extent2] ON [Extent1].[UserID] = [Extent2].[ID]
WHERE (0 = [Extent1].[SocialNetwork]) AND (([Extent1].[Link] = @p__linq__0) OR (([Extent1].[Link] IS NULL) AND (@p__linq__0 IS NULL))) AND ([Extent2].[TenantID] = @p__linq__1)',N'@p__linq__0 nvarchar(4000),@p__linq__1 int',@p__linq__0=N'linkedin.com/in/a-profile-as',@p__linq__1=5
如您所见,在使用FirstOrDefault进行过滤之前,我使用ToList来获取数据.而且,通常不建议执行急切的ToList.为什么在使用FirstOrDefault时,Entity Framework将选择放入选择中?
很抱歉我的英语水平,希望我能正确解释我的问题.
编辑:
当数据库中不存在“ linkedinurl”值,并且只有当它不存在时,我才添加了一些有趣的东西,两个查询都花费不到1秒的时间.
编辑2:
写完评论后,我想补充一下我们的数据库在Azure上.而且该问题不会出现在简单的SQLEXPRESS数据库上.而且,此问题在4或5天前出现.
解决方法:
那是因为在where().Select()组合之后使用FirstOrDefault.
第一个查询会像这样更好地工作:
id = Container.SocialNetworks.FirstOrDefault(a => a.SocialNetwork == EnumSocialNetwork.LinkedIn && a.Link == linkedinurl && a.User.TenantID == Container.TenantId)?.UserID;
如您所见,我使用FirstOrDefault就像使用Where一样,但是这将加载整个对象,如注释中所述.
为什么您的秒查询更快?因为您以ToList()结束了查询,所以FirstOrDefault部分仅适用于您的c#代码,因此,在行被加载之后,而不是通过双击将行加载到DB上.
编辑:
尝试这两行可能会更好地突出根本原因:
1.尝试订购您的套装:
id = Container.SocialNetworks
.Where(a => a.SocialNetwork == EnumSocialNetwork.LinkedIn && a.Link == linkedinurl && a.User.TenantID == Container.TenantId)
.OrderBy(t => t.UserID).Select(i => i.UserID).FirstOrDefault();
2.使用聚合函数:
id = Container.SocialNetworks
.Where(a => a.SocialNetwork == EnumSocialNetwork.LinkedIn && a.Link == linkedinurl && a.User.TenantID == Container.TenantId)
.Min(i => i.UserID);
标签:entity-framework-6,sql,c,net,entity-framework 来源: https://codeday.me/bug/20191211/2106731.html