Я использую LINQ для вызова SQL Server sproc. Иногда я получаю InvalidOperationException: требуемый идентификатор столбца не существует в результатах. Столбец существует в результатах sproc. Я использую "использование", как предлагается в старой статье. Любые идеи, почему это может случиться наугад?
фрагмент кода:
using (MyDataContext dataContext = new MyDataContext(context.ConnectionString))
{
alertQueueList = dataContext.ExecuteQuery<AlertQueue>("exec dbo.my_AlertQueue_Dequeue @RowsToReturn = {0}", "10");
// To handle exception when no rows are returned by sproc
ret = alertQueueList.ToList();
}
Исключение выбрано в ExecuteQuery().
Exception:
System.InvalidOperationException: The required column 'ID' does not exist in the results.
at System.Data.Linq.SqlClient.ObjectReaderCompiler.ObjectReaderBase'1.GetColumnOrdinals(NamedColumn[] namedColumns)
at System.Data.Linq.SqlClient.ObjectReaderCompiler.ObjectReaderBase'1..ctor(ObjectReaderSession'1 session, NamedColumn[] namedColumns, Object[] globals, Object[] arguments, Int32 nLocals)
at System.Data.Linq.SqlClient.ObjectReaderCompiler.ObjectReaderSession'1.CreateReader[TObject](Func'2 fnMaterialize, NamedColumn[] namedColumns, Object[] globals, Int32 nLocals, Boolean disposeDataReader)
at System.Data.Linq.SqlClient.ObjectReaderCompiler.ObjectReaderFactory'2.Create(DbDataReader dataReader, Boolean disposeDataReader, IReaderProvider provider, Object[] parentArgs, Object[] userArgs, ICompiledSubQuery[] subQueries)
at System.Data.Linq.SqlClient.SqlProvider.Execute(Expression query, QueryInfo queryInfo, IObjectReaderFactory factory, Object[] parentArgs, Object[] userArgs, ICompiledSubQuery[] subQueries, Object lastResult)
at System.Data.Linq.SqlClient.SqlProvider.ExecuteAll(Expression query, QueryInfo[] queryInfos, IObjectReaderFactory factory, Object[] userArguments, ICompiledSubQuery[] subQueries)
at System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Execute(Expression query)
at System.Data.Linq.DataContext.ExecuteMethodCall(Object instance, MethodInfo methodInfo, Object[] parameters)
at System.Data.Linq.DataContext.ExecuteQuery[TResult](String query, Object[] parameters)
at MyNamespace.Logic.AlertQueueLogic.GetForProcessing(IMyNamespaceContext context) in c:\\foo\\AlertQueueLogic.cs:line 26
at Connect.Processor.AlertProcessor.DequeueAlerts() in c:\\foo\\AlertProcessor.cs:line 123
sproc content: я вставляю код внутри sproc ниже:
НАЧАТЬ ПЕРЕВОД;
UPDATE TOP (@RowsToReturn) dbo.AlertQueue WITH (ROWLOCK, UPDLOCK, READPAST)
SET AlertStatus = @AlertStatus_Processing,
LastLockedDttm = @CurrentDttm
OUTPUT INSERTED.ID INTO @OutputRows
WHERE <my predicate>
COMMIT TRANSACTION;
SELECT [ID], [ScheduleID], [TriggerName], [AlertStatus], [LastLockedDttm], [RetryCount], [LastRetryDttm], [LastResponse], [DateCreated], [Version]
FROM dbo.AlertQueue
WHERE ID IN (SELECT ID FROM @OutputRows)
Sproc был вызван из кода С# в TransactionScope(), который добавил сериализуемый уровень изоляции для транзакции, которая противоречила подсказке READPAST в sproc. Удаление READPAST или создание TransactionScope() в качестве READCOMITTED уровня изоляции устранили проблему.
Возможно, это зависит от параметра @RowsToReturn, который вы всегда инициализируете до 10. Возможно, в некоторых случаях в некоторой таблице запрашивается менее 10 строк в sproc.
Убедитесь, что у вас есть столбец с именем "ID", и он должен быть основным ключом. Попробуй это.