This scenario involves: ASP.NET, Visual Studio 2010, SQL Server 2008 R0, and SubSonic 3.0.0.2
I have isolated this error to a situation where the collection is not being modified in any apparent way (no add/remove of collection items, no sorts, etc). So, my understanding is that this is a threading issue of some kind, correct?
The error occurs in SubSonic.DataProviders.DbDataProvider, in the FindTable method of DbDataProvider.cs. My method for reproducing the error is basically calling this method multiple times in quick succession from the UI layer. Not graceful, but it's the best I have so far since the error occurs intermittently for my users in production.
Here is the complete source code for DbDataProvider.cs: https://github.com/subsonic/SubSonic-3.0/blob/master/SubSonic.Core/DataProviders/DbDataProvider.cs
The FindTable method is where the error occurs:
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;
}
Here is the 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:\TFS\SubSonic.Core\DataProviders\DbDataProvider.cs:line 345
at MyCorp.DataAccessLayer.SomeDb.FindTable(String tableName)
at SubSonic.Repository.SubSonicRepository`1.GetTable() in D:\TFS\SubSonic.Core\Repository\SubSonicRepository.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)
Any ideas what would be causing this and how it can be resolved? I tried introducing a lock but that seemed to introduce a big performance hit.
Everything was working fine in our prior release that used SubSonic 2.2. Once we migrated to SubSonic 3.x, we detected no problems in our DEV, TEST, or UAT environments. This only became an issue once we went to production. It doesn't seem to be related to load, either, as I can reproduce the error against our production database from a local application development environment with no other active user connections to the database.
I don't anything about SubSonic but it might help to pull Schema.Tables into a variable that forces execution (e.g., Schema.Tables.ToArray()) for the double pass of the erroring line.