此场景涉及:ASP.NET、Visual Studio 2010、SQL Server 2008 R0和SubSonic 3.0.0.2
我已经将此错误隔离为没有以任何明显的方式修改集合的情况(没有添加/删除集合项,没有排序等)。所以,我的理解是,这是某种线程问题,对吗?
该错误发生在SubSonic.DataProvider.DbDataProvider中,在DbDataProvider.cs的FindTable方法中。我再现该错误的方法基本上是从UI层连续快速多次调用该方法。虽然不太优雅,但这是我迄今为止最好的一次,因为我的用户在生产中会间歇性地出现错误。
以下是DbDataProvider.cs的完整源代码:https://github.com/subsonic/SubSonic-3.0/blob/master/SubSonic.Core/DataProviders/DbDataProvider.cs
FindTable方法是发生错误的地方:
public ITable FindTable(string tableName)
{
// The following line throws the error.
var result = Schema.Tables.FirstOrDefault(x => x.Name.Equals(tableName, StringComparison.InvariantCultureIgnoreCase)) ??
Schema.Tables.FirstOrDefault(x => x.ClassName.Equals(tableName, StringComparison.InvariantCultureIgnoreCase));
return result;
}
这是StackTrace:
at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
at System.Collections.Generic.List`1.Enumerator.MoveNextRare()
at System.Collections.Generic.List`1.Enumerator.MoveNext()
at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source, Func`2 predicate)
at SubSonic.DataProviders.DbDataProvider.FindTable(String tableName) in D:TFSSubSonic.CoreDataProvidersDbDataProvider.cs:line 345
at MyCorp.DataAccessLayer.SomeDb.FindTable(String tableName)
at SubSonic.Repository.SubSonicRepository`1.GetTable() in D:TFSSubSonic.CoreRepositorySubSonicRepository.cs:line 42
at MyCorp.DataAccessLayer.grid_type_obj.Init()
at MyCorp.DataAccessLayer.grid_type_obj..ctor()
at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean skipCheckThis, Boolean fillCache)
有什么想法会导致这种情况,以及如何解决?我试着推出一把锁,但这似乎带来了巨大的性能冲击。
在我们之前使用SubSonic 2.2的版本中,一切都很好。一旦我们迁移到SubSonic 3.x,我们在DEV、TEST或UAT环境中就没有发现任何问题。这只是在我们投入生产后才成为一个问题。它似乎也与加载无关,因为我可以在没有其他活动用户连接到数据库的情况下,从本地应用程序开发环境中重现生产数据库的错误。
我对SubSonic一无所知,但它可能有助于将Schema.Tables拉到一个变量中,该变量强制执行(例如Schema.Tables.ToArray()),以完成错误行的双重传递。