c# - 运行 SqlQuery EF 时 FieldNameLookup.GetOrdinal 中的索引超出范围异常

标签 c# .net asp.net-mvc entity-framework azure-application-insights

当运行这样的代码时,我们最终会得到一个IndexOutOfRange异常:

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

,其中 ExecuteStoredProcedure 执行以下操作:

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());
}

我们无法在本地重现该问题,但使用 Application Insights 时会经常记录异常。以下是调用堆栈摘录:

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)

我们尝试通过以下方式在本地重现该问题:

  • 使存储过程失败。
  • 使存储过程返回 0 个结果。
  • 通过重命名某些模型属性导致映射问题。

没有成功。

通常,当您使用 ADO.NET 时,由于 datareader 中的映射错误而发生此错误,但情况并非如此,因为我们使用 EF 6而且也不是经常发生,所以我们无法真正找到问题出在哪里。

最佳答案

此问题与将存储过程的结果 与声明为与存储过程的输出绑定(bind)的模型 绑定(bind)有关。

如果存储过程检索的列多于模型具有的属性,即使模型满足(因为所有属性都可以与存储过程输出的列匹配),内部也会引发异常,因为模型不满足'具有存储某些存储过程输出值的属性。

所以,这可以通过两种方式解决:要么

  • 在模型中添加属性以包含存储的列 程序,或
  • 删除存储过程输出中不必要的列。

第二种方法通常更好,因为这个问题表明不再需要存储过程返回的某些数据,因此删除存储过程中不需要的代码会更干净、性能更高。

关于c# - 运行 SqlQuery EF 时 FieldNameLookup.GetOrdinal 中的索引超出范围异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51143207/

相关文章:

c# - Xamarin.Forms ListView 大小到内容

.net - CodeDom 调用构造函数

c# - Asp net MVC 5 和带有 linq 的列表框

asp.net-mvc - SignalR:无法连接到本地或任何其他 IP 地址

c# - 从 Int 表达式创建 bool Linq to SQL 表达式

c# - 这种情况设置EnableEventValidation ="false"是否存在安全风险?

c# - 在编写代码时,确定类型是否为 IDisposable 的最快方法是什么

c# - C#中的数组如何部分实现IList<T>?

.net - Entity Framework 4.3 遇到的最大池大小

c# - 你调用的对象是空的