2012-09-26 68 views
1

我正在使用實體框架4.1查詢SQL Server 2008數據庫。不幸的是每次我們經常得到下面的異常:實體框架 - System.IndexOutOfRangeException

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

更新** 更新了我的代碼緩存。

我使用Google搜索並找到答案,但找不到明確答案的根本原因。一些遇到這個問題的人可以分享一個解決方案嗎?

謝謝。

+0

你的上下文是否與數據庫不同步? (數據庫列與類屬性不匹配?) –

+0

問題只是隨機發生的,我不懷疑它是同步問題。 –

+0

相關:http://stackoverflow.com/questions/12617639/weird-random-exceptions –

回答

4

調用.Count()執行查詢。我不認爲.First()會再次執行它,但也許是這樣,並且在這些調用之間有所改變。你可以嘗試重寫查詢爲:

(from entity in result 
where entity.employeeId == employeeID 
select entity).FirstOrDefault() ?? new EmployeeEntity(); 
+0

我已經用緩存更新了上面的代碼。這可能導致它嗎? –

+0

@dskh很好的捕獲,它重新執行查詢,計數不獲取數據,它只是執行一個SQL計數,FirstOrDefault看起來像這裏正確的解決方案 – Guillaume86

+0

@ Guillaume86,謝謝你的回答什麼是IS代表爲什麼count不會獲取數據? –

0

嘗試返回這樣的:

return entityResult.First(e => e.employeeId == employeeID); 
0

任何要求的IEnumerable或IQueryable的將重新執行查詢功能...這就是爲什麼它是不是好把這樣的東西放在循環中。您結束了對數據庫的大量查詢。至於爲什麼它變得我會用。任何(),而不是數量的異常以確定結果

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

的長度雖然邏輯有點混亂,因爲要返回單個EmployeeEntity和查詢建議你期待只有一回。所以你可以使用

entityResult.Single<Employee>() 

如果返回多於一個,除非你不能處理調用者中的異常,否則它將拋出異常。然後SingleOrDefault可能是最好的,然後只檢查null,沒有計數或任何檢查。

只是有些建議總是有不止一種方法去做點什麼