编程语言
首页 > 编程语言> > c#-使用实体框架进行简单请求的执行时间较长

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