1

SQL Server 2008 データベースをクエリするエンティティ フレームワーク 4.1 を使用しています。残念ながら、以下の例外が頻繁に発生します。

<ExceptionType>System.IndexOutOfRangeException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType>
  <Message>Index was outside the bounds of the array.</Message>



at System.Data.SqlClient.SqlDataReader.ReadColumnHeader(Int32 i)
   at System.Data.SqlClient.SqlDataReader.IsDBNull(Int32 i)
   at System.Data.Common.Internal.Materialization.Shaper.ErrorHandlingValueReader`1.GetValue(DbDataReader reader, Int32 ordinal)
   at System.Data.Common.Internal.Materialization.Shaper.GetPropertyValueWithErrorHandling[TProperty](Int32 ordinal, String propertyName, String typeName)
   at lambda_method(Closure , Shaper )
   at System.Data.Common.Internal.Materialization.Shaper.HandleEntityAppendOnly[TEntity](Func`2 constructEntityDelegate, EntityKey entityKey, EntitySet entitySet)
   at lambda_method(Closure , Shaper )
   at System.Data.Common.Internal.Materialization.Coordinator`1.ReadNextElement(Shaper shaper)
   at System.Data.Common.Internal.Materialization.Shaper`1.SimpleEnumerator.MoveNext()
   at System.Linq.Enumerable.First[TSource](IEnumerable`1 source)
   at System.Linq.Queryable.First[TSource](IQueryable`1 source)
   at OnlineSelfService.Business.ContentServiceBusiness.GetPageContent(Int32 pageId)</StackTrace>

実際のサンプル コード:

//Caller
  public EmployeeEntity GetEmployeeDetail(int employeeID)
    {
         IQueryable<Employee> result=null;
         if (myCaching.Contains("Employee"))
            {
                result = (IQueryable<Employee>)myCaching["Employee"];
            }
            else
            {
                result = dataAccess.GetEmployeeDetail();
                myCaching.AddToCache("Employee", result); //Expire in 2min
            }

            IQueryable<Employee> entityResult = from entity in result
                                                         where entity.employeeId == employeeID
                                                         select entity;
       if (entityResult.Count<Employee>() > 0)
                return entityResult.First<Employee>();
            return new EmployeeEntity();
   }

}

//DAL
public IQueryable<Employee> GetEmployeeDetail()
{
    DatabaseEntities ent = new DatabaseEntities(this._connectionString);
    IQueryable<Employee> result = from employee in ent.EmployeeEntity
                                           select employee;

    return result;
}

更新 ** キャッシュを使用してコードを更新しました。

検索して回答するためにグーグルで検索しましたが、根本的な原因に関する決定的な回答を見つけることができませんでした。この問題に直面した人は解決策を共有できますか。

ありがとうございました。

4

3 に答える 3

4

.Count() を呼び出すと、クエリが実行されます。私は .First() がそれを再び実行するとは思わないでしょうが、おそらくそうであり、これらの呼び出しの間に何かが変更されました。クエリを次のように書き直してみてください。

(from entity in result
where entity.employeeId == employeeID
select entity).FirstOrDefault() ?? new EmployeeEntity();
于 2012-09-26T15:09:40.573 に答える
0

次のように返してみてください。

return entityResult.First(e => e.employeeId == employeeID);
于 2012-10-05T14:08:19.050 に答える
0

IEnumerable または IQueryable で呼び出された関数は、クエリを再実行します...そのため、そのようなことをループに入れるのは良くありません。DBへの大量のクエリが終了します。例外が発生する理由については、 count の代わりに .Any() を使用して、結果の長さを判断します

return (entityResult.Any<Employee>() > 0) ? entityResult.First<Employee>() : new EmployeeEntity();

単一の EmployeeEntity を返す必要があり、クエリは 1 つだけが返されることを期待していることを示唆しているため、ロジックは少し混乱します。だからあなたはただ使うことができます

entityResult.Single<Employee>() 

呼び出し元で例外を処理できない場合を除き、複数が返されると例外がスローされます。次に、SingleOrDefault が最適な場合があり、null をチェックするだけで、カウントやチェックはまったくありません。

何かを行うには常に複数の方法があります

于 2012-10-05T20:10:57.350 に答える