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

Calling .Count() executes the query. I wouldn't think the .First() would execute it again but maybe it is, and something has changed in between these calls. You could try rewriting the query as:

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

在 IEnumerable 或 IQueryable 上调用的任何函数都将重新执行查询......这就是为什么将这样的事情放在循环中是不好的。您最终会对数据库进行大量查询。至于为什么会出现异常,我会使用 .Any() 而不是 count 来确定结果的长度

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

尽管逻辑有点混乱,因为您想返回一个 EmployeeEntity 并且查询表明您只期望返回一个。所以你可以使用

entityResult.Single<Employee>() 

如果返回多个,除非您无法在调用者中处理异常,否则将引发异常。然后 SingleOrDefault 可能是最好的,然后只检查 null 而根本没有计数或任何检查。

只是一些建议,总有不止一种方法可以做某事

于 2012-10-05T20:10:57.350 回答
0

Try to return like this:

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