【问题标题】:Strange LINQ Exception奇怪的 LINQ 异常
【发布时间】:2011-10-02 23:46:05
【问题描述】:

我有一个与theseposts 类似的问题:我单独发帖是为了提供关于我的问题的更多信息,以及我为调试它所采取的步骤。

该网站基本上可以正常工作 12 小时以上,然后突然停止工作。我将开始在以前运行良好的 LINQ 查询中抛出奇怪的异常。

我在这篇文章的底部包含了堆栈跟踪。

根据类似 SO 帖子中的建议,我通过直接从服务器资源管理器中的数据库中拖动表来删除并重新制作了我的 DBML。对比 Git 中的新旧,发现有几个字段不同:

  • varchar(255) 的一个实例在 dbml 中被设置为 nchar(10)
  • 以前在 dbml 中没有 NOT NULL 的两个 varchar(255) 实例
  • 一个 int(4) 字段以前在 dbml 中没有 NOT NULL

一些观察/注释:

  • 网站在一段时间内可以 100% 正常运行,然后就开始抛出这些错误
  • 我可以通过在 IIS 中重新启动站点来临时修复它或通过重新启动 MSSQL 服务器,但问题通常会在第二天出现
  • 我不知道如何手动复制它
  • 对于某些页面,我可以多次重新加载它们并获得不同但相似的异常
    • 我可能会在调用.Count() 的线路上获得InvalidOperationException,然后重新加载它并在调用.Any() 或.First() 的线路上获得IndexOutOfRangeExcpetion
    • 尽管异常发生了变化,但无论如何我总是在某些页面上遇到异常 - 它们永远不会暂时消失
  • 我正在使用存储库模式,因此我的每个类都有一个带有私有 DataContext 成员的存储库类 - 这可能是为什么?
  • 该站点的部分视图包含来自 db 的导航项,这似乎总是可以正常加载,但从 db 加载其他内容失败。也许这个块被缓存了,这就是它继续工作的原因?

似乎总是在这一行抛出异常:

System.Data.Linq.SqlClient.SqlProvider.Execute(Expression query, QueryInfo queryInfo, IObjectReaderFactory factory, Object[] parentArgs, Object[] userArgs, ICompiledSubQuery[] subQueries, Object lastResult) +4539

对为什么会发生这种情况以及如何解决问题有什么想法吗?

编辑1:我已经在相应的堆栈跟踪上方添加了相关代码。执行最后一行代码时抛出异常。

这是我在重新启动站点之前能够复制粘贴的几个堆栈跟踪:

IEnumerable<Chapter> toc = (from c in db.Chapters
    where c.Sections.Any()
    orderby c.ChapterNumber ascending
    select c);
return toc.Count();

[InvalidOperationException: Sequence contains more than one element]
   System.Data.Linq.SqlClient.SqlProvider.Execute(Expression query, QueryInfo queryInfo, IObjectReaderFactory factory, Object[] parentArgs, Object[] userArgs, ICompiledSubQuery[] subQueries, Object lastResult) +4539
   System.Data.Linq.SqlClient.SqlProvider.ExecuteAll(Expression query, QueryInfo[] queryInfos, IObjectReaderFactory factory, Object[] userArguments, ICompiledSubQuery[] subQueries) +207
   System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Execute(Expression query) +500
   System.Data.Linq.DataQuery`1.System.Linq.IQueryProvider.Execute(Expression expression) +41
   System.Linq.Queryable.Count(IQueryable`1 source) +352
   MvcPaging.PagedList`1.Initialize(IQueryable`1 source, Int32 index, Int32 pageSize, Nullable`1 totalCount) in C:\path\to\my\project\MvcPaging\src\MvcPaging\PagedList.cs:63
   MvcPaging.PagedList`1..ctor(IEnumerable`1 source, Int32 index, Int32 pageSize, Nullable`1 totalCount) in C:\path\to\my\project\MvcPaging\src\MvcPaging\PagedList.cs:16
   MvcPaging.PagedList`1..ctor(IEnumerable`1 source, Int32 index, Int32 pageSize) in C:\path\to\my\project\MvcPaging\src\MvcPaging\PagedList.cs:10
   MvcPaging.PagingExtensions.ToPagedList(IEnumerable`1 source, Int32 pageIndex, Int32 pageSize) in C:\path\to\my\project\MvcPaging\src\MvcPaging\PagingExtensions.cs:77
   MyNamespace.Controllers.ChaptersController.TableOfContents(Nullable`1 page) in C:\path\to\my\project\Controllers\ChaptersController.cs:73
   lambda_method(Closure , ControllerBase , Object[] ) +118
   System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +264
   System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +39
   System.Web.Mvc.<>c__DisplayClass15.<InvokeActionMethodWithFilters>b__12() +129
   System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) +784922
   System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +314
   System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +784976
   System.Web.Mvc.Controller.ExecuteCore() +159
   System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +335
   System.Web.Mvc.<>c__DisplayClassb.<BeginProcessRequest>b__5() +62
   System.Web.Mvc.Async.<>c__DisplayClass1.<MakeVoidDelegate>b__0() +20
   System.Web.Mvc.<>c__DisplayClasse.<EndProcessRequest>b__d() +54
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +453
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +37




var contentTop = (new PageRepository()).FindAllPages().Where(p => p.Slug == "login-top");
var contentBot = (new PageRepository()).FindAllPages().Where(p => p.Slug == "login-bottom");
ViewData["ContentAboveTheBox"] = (contentTop.Any() ? contentTop.First().HTML : String.Empty);



[IndexOutOfRangeException: Index was outside the bounds of the array.]
   System.Data.Linq.SqlClient.SqlProvider.Execute(Expression query, QueryInfo queryInfo, IObjectReaderFactory factory, Object[] parentArgs, Object[] userArgs, ICompiledSubQuery[] subQueries, Object lastResult) +4539
   System.Data.Linq.SqlClient.SqlProvider.ExecuteAll(Expression query, QueryInfo[] queryInfos, IObjectReaderFactory factory, Object[] userArguments, ICompiledSubQuery[] subQueries) +207
   System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Execute(Expression query) +500
   System.Data.Linq.DataQuery`1.System.Linq.IQueryProvider.Execute(Expression expression) +50
   System.Linq.Queryable.First(IQueryable`1 source) +383
   MyNamespace.Controllers.AccountController.SetLoginContentAreas() in C:\path\to\my\project\Controllers\AccountController.cs:112
   MyNamespace.Controllers.AccountController.LogIn(String userName, String password, Nullable`1 rememberMe, String returnUrl, Nullable`1 IsEnc) in C:\path\to\my\project\Controllers\AccountController.cs:122
   MyNamespace.Controllers.AccountController.LoginPassThru() in C:\path\to\my\project\Controllers\AccountController.cs:82
   lambda_method(Closure , ControllerBase , Object[] ) +79
   System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +264
   System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +39
   System.Web.Mvc.<>c__DisplayClass15.<InvokeActionMethodWithFilters>b__12() +129
   System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) +784922
   System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +314
   System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +784976
   System.Web.Mvc.Controller.ExecuteCore() +159
   System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +335
   System.Web.Mvc.<>c__DisplayClassb.<BeginProcessRequest>b__5() +62
   System.Web.Mvc.Async.<>c__DisplayClass1.<MakeVoidDelegate>b__0() +20
   System.Web.Mvc.<>c__DisplayClasse.<EndProcessRequest>b__d() +54
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +453
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +371

还有一个InvalidCastException 抛出在一个特定的页面上。更新 dbml 似乎无法解决此问题,但重新启动站点可以。

【问题讨论】:

  • 我已经在相应的堆栈跟踪上方发布了 LINQ 查询

标签: .net sql asp.net-mvc linq


【解决方案1】:

您是否在每个请求上处理您的 DataContext(您应该这样做)?或者您是否有一个永远存在的 DataContext(听起来可能是这种情况)?

听起来可能是线程问题。

【讨论】:

  • 我目前没有针对每个请求处理 DataContexts。我有一个作为扩展 System.Web.Routing.RouteBase 的类的私有成员,另一个扩展了 MembershipProvider - 也许这两个中的一个永远存在?我所有的存储库模型也将其作为私有成员,但它们始终在控制器方法中初始化。
  • 在我的存储库类中实现IDisposable 是否是个好主意,将DataContext 保留为私有成员,并在repo 类的Dispose() 方法调用db.Dispose() 中?控制器逻辑将更新为使用using(var pageRepo = new PageRepository()) { ... }。只是想知道这是否是正确的方法。
  • DataContexts 的生命周期应该很短。而且它们不是线程安全的。如果两个线程试图访问/更改与 DataContext 关联的对象,它可能会变得“损坏”......永远。您应该在每个请求上处理 DataContext ...并为每个请求实例化一个新的。有些人选择将其存储在 HttpContext.Current.Items 中并绑定到 RequestEnd 事件以进行处置。
  • 是的,这将是一个非常好的主意,假设您不想跨多个存储库共享单个 DataContext。
  • 替代方案是 using(var dc = new MyDc()) { var repo1 = new Repo1(dc); var repo2 = 新的 Repo2(dc); }
【解决方案2】:

看起来在您的 LINQ 中,您正在调用 .Single()(或类似的),如果 IQueryable 集合包含多个元素,则会引发该异常。

下一次,请发布您的代码,而不仅仅是您的堆栈跟踪。

【讨论】:

  • 我在堆栈跟踪中的任何地方都看不到 Single。并且“索引超出了数组的范围”来自 QueryProvider 本身。
  • 杰夫是对的。我确实在其他地方给.Single() 打了几次电话,但这些电话都包裹在try..catch 块中并且工作正常。我遇到的问题是它总是工作到某个时间点,然后停止工作。
  • .Single() 和.SingleOrDefault() 专门抛出了异常消息:“序列包含多个元素”(位于堆栈顶部),这就是我回答的基础。
猜你喜欢
  • 2011-08-19
  • 1970-01-01
  • 2019-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多