【问题标题】:LINQ and .COUNT timing outLINQ 和 .COUNT 超时
【发布时间】:2009-04-06 07:04:03
【问题描述】:

我有一个一般性问题,并对 LINQ 和超时感到好奇。

我有一个正在运行的应用程序,我收到以下代码超时。

下面的代码,很正常,没看出有什么问题:

private static tblUser GetUserLinq(string email, string password) { DataContext db = new DataContext();

        var tblUsers = from user in db.tblUsers
                           where user.EmailAddress == email
                           && user.Password == password
                           select user;

        if (tblUsers.Count() == 0)
            return null;

        return tblUsers.First();
    }

但是会出现以下超时,相当多:

        if (tblUsers.Count() == 0)

这里是例外

超时。在操作完成之前超时时间已过或服务器没有响应。 - System.Data.SqlClient.SqlException:超时已过期。在操作完成之前超时时间已过或服务器没有响应。 在 System.Data.SqlClient.SqlConnection.OnError(SqlException 异常,布尔 breakConnection) 在 System.Data.SqlClient.SqlInternalConnection.OnError(SqlException 异常,布尔 breakConnection) 在 System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj) 在 System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior,SqlCommand cmdHandler,SqlDataReader dataStream,BulkCopySimpleResultSet bulkCopyHandler,TdsParserStateObject stateObj) 在 System.Data.SqlClient.SqlDataReader.ConsumeMetaData() 在 System.Data.SqlClient.SqlDataReader.get_MetaData() 在 System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds,RunBehavior runBehavior,字符串 resetOptionsString) 在 System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior,RunBehavior runBehavior,布尔 returnStream,布尔异步) 在 System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior,RunBehavior runBehavior,布尔 returnStream,String 方法,DbAsyncResult 结果) 在 System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior,RunBehavior runBehavior,布尔 returnStream,String 方法) 在 System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior 行为,字符串方法) 在 System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior 行为) 在 System.Data.Common.DbCommand.ExecuteReader() 在 System.Data.Linq.SqlClient.SqlProvider.Execute(表达式查询,QueryInfo queryInfo,IObjectReaderFactory 工厂,Object[] parentArgs,Object[] userArgs,ICompiledSubQuery[] subQueries,Object lastResult) 在 System.Data.Linq.SqlClient.SqlProvider.ExecuteAll(表达式查询,QueryInfo[] queryInfos,IObjectReaderFactory 工厂,Object[] userArguments,ICompiledSubQuery[] subQueries) 在 System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Execute(表达式查询) 在 System.Data.Linq.DataQuery1.System.Linq.IQueryProvider.Execute[S](Expression expression) at System.Linq.Queryable.Count[TSource](IQueryable1 来源) 在 C:\Actions.cs:line 104 中的 Actions.GetUserLinq(String email, String password) 在 C:\Actions.cs:line 33 中的登录(字符串电子邮件,字符串密码)处

我对为什么超时的一些想法:

count需要统计那个表的记录数,这不是我们要的 如果我们试图查找记录是否存在,那么我们应该使用以下代码:

        var tblUsers = (from user in db.tblUsers
                           where user.EmailAddress == email
                           && user.Password == password
                           select user).FirstOrDefault(u => u.UserId <0) ;

否则我有点困惑为什么 LINQ 会超时

我注意到的另一件事是,如果您通过 SQL 企业管理器直接在机器上运行以下 SQL,它也会超时,这表明它可能是一个锁定问题,但是调用该表的唯一应用程序是 LINQ

从 tbluser 中选择计数(用户 ID)

欢迎评论

【问题讨论】:

  • 您是否以纯文本形式存储密码?我建议使用 SHA1 哈希或更好的盐渍哈希。
  • 是的,我同意,但这不是这里的问题

标签: .net linq linq-to-sql exception


【解决方案1】:

您应该检查用户表的索引。用户名/密码索引可能会有所帮助。

【讨论】:

  • 我遇到了类似的问题,向我的表添加唯一键解决了这个问题。感谢您让我走上正轨!
【解决方案2】:

如果即使使用 SQL Enterprise Manager 查询也超时,那应该是您首先解决的问题。

完全不考虑 LINQ - 确保 没有 else 正在访问数据库,并查看该查询是否仍然超时。在其上运行查询分析器。

当然,如果你只是想获得第一个用户,你应该重写你的方法:

private static tblUser GetUserLinq(string email, string password) 
{ 
    DataContext db = new DataContext();

    var tblUsers = from user in db.tblUsers
                       where user.EmailAddress == email
                       && user.Password == password
                       select user;

    return tblUsers.FirstOrDefault();
}

(那里不需要“u => u.UserId

如果没有结果,FirstOrDefault 已经返回 null,那应该没问题。

听起来你的数据库有更大的问题。 EmailAddress 和 Password 是否都已正确编入索引?

【讨论】:

  • 这就是我在阅读本文之前的想法thepursuitofalife.com/…
  • 我看不到任何东西表明 FirstOrDefault without 参数会失败。你看到什么问题?如果您点击链接并查看 ScottGu 的实际评论,那么他正在使用 useful 谓词。
【解决方案3】:

顺便说一句,尽量远离这种模式:

  if (tblUsers.Count() == 0)
            return null;

有一个很棒的扩展方法,叫做 Any(),它会为你生成更好的 SQL:

if ( !tblUsers.Any())
    return null;

【讨论】:

    【解决方案4】:

    在本地运行查询超时这一事实表明您需要在表上建立一些索引。如果您在启用“执行计划”的管理工作室中运行查询,那么您应该能够看到需要创建哪些索引。

    这种情况可能是由于查询超时,因此您将无法获得执行计划,因此您将不得不使用“估计执行计划”功能。 (这些图标看起来像连接在一起的蓝色和绿色小盒子)

    【讨论】:

    • 太好了,我刚刚尝试过,但从未完成 :-( 由于这是一台实时机器(机器上没有用户),我刚刚重新启动 SQL Server 以释放所有锁。现在运行正常。该表只有 254 条记录,但我刚刚索引了电子邮件和密码字段。我将进行监控。
    猜你喜欢
    • 2012-06-24
    • 2014-05-20
    • 1970-01-01
    • 1970-01-01
    • 2022-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多