Index out of range exception in FieldNameLookup.GetOrdinal when running SqlQuery EF

ε祈祈猫儿з 提交于 2021-01-21 08:52:50

问题


We are getting eventually an IndexOutOfRange exception when running code like this:

result.Data = dbOptima.Database.ExecuteStoredProcedure(
    task,
    StoredProcedureValues.PROC_GET_TASKS).ToList();

,where ExecuteStoredProcedure does the following:

public static IEnumerable<TResult> ExecuteStoredProcedure<TResult>(this Database database, IStoredProcedure<TResult> procedure, string procedureName)
{
    var parameters = CreateSqlParametersFromProperties(procedure);
    var format = CreateSPCommand<TResult>(parameters, procedureName);

    return database.SqlQuery<TResult>(format, parameters.Cast<object>).ToArray());
}

We cannot reproduce the problem locally, but using Application Insights the exception is registered quite often. The following is a call stack extract:

System.IndexOutOfRangeException:
   at System.Data.ProviderBase.FieldNameLookup.GetOrdinal (System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
   at System.Data.SqlClient.SqlDataReader.GetOrdinal (System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
   at System.Data.Entity.Core.Query.InternalTrees.ColumnMapFactory.TryGetColumnOrdinalFromReader (EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
   at System.Data.Entity.Core.Query.InternalTrees.ColumnMapFactory.CreateColumnMapFromReaderAndClrType (EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
   at System.Data.Entity.Core.Objects.ObjectContext.InternalTranslate (EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
   at System.Data.Entity.Core.Objects.ObjectContext.ExecuteStoreQueryInternal (EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
   at System.Data.Entity.Core.Objects.ObjectContext+<>c__DisplayClass65`1.<ExecuteStoreQueryReliably>b__64 (EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
   at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction (EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
   at System.Data.Entity.Core.Objects.ObjectContext+<>c__DisplayClass65`1.<ExecuteStoreQueryReliably>b__63 (EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
   at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute (EntityFramework.SqlServer, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
   at System.Data.Entity.Core.Objects.ObjectContext.ExecuteStoreQueryReliably (EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
   at System.Data.Entity.Core.Objects.ObjectContext.ExecuteStoreQuery (EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
   at System.Data.Entity.Internal.LazyEnumerator`1.MoveNext (EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
   at System.Collections.Generic.List`1..ctor (mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
   at System.Linq.Enumerable.ToList (System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)

We've tried to reproduce the problem locally by:

  • making the stored procedure fail.
  • making the stored procedure return 0 results.
  • causing a mapping problem by renaming some model property.

with no success.

Typically, this error happens due to a mapping error in the datareader when you use ADO.NET, but this is not the case since we use EF 6 and it does not happen always, so we cannot really find where the problem is.


回答1:


The problem is related to binding the result of the stored procedure with the model declared to be bound with the output of the stored procedure.

If the stored procedure retrieves more columns than the properties that the model has, even though the model is satisfied (because all the properties can be matched with columns of the stored procedure output), internally an exception is raised cause the model doesn't have properties to store some of the store procedure output values.

So, this can be fixed in two ways: either

  • adding properties in the model to contain the columns of the stored procedure, or
  • removing the unnecessary columns of the stored procedure output.

The second approach is normally better, since this issue is making evident that some data returned by the stored procedure is no longer required, so it would be cleaner and more performant to remove the unneeded code in the stored procedure.



来源:https://stackoverflow.com/questions/51143207/index-out-of-range-exception-in-fieldnamelookup-getordinal-when-running-sqlquery

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!