我正在使用查询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;
}
UPDATE ** 使用缓存更新了我的代码。
我用谷歌搜索并回答但找不到根本原因的确定答案。面对这个问题的一些人是否可以分享决议。
谢谢。
答案 0 :(得分:4)
调用.Count()执行查询。我不认为.First()会再次执行它,但也许它会在这些调用之间发生变化。您可以尝试将查询重写为:
(from entity in result
where entity.employeeId == employeeID
select entity).FirstOrDefault() ?? new EmployeeEntity();
答案 1 :(得分:0)
尝试像这样返回:
return entityResult.First(e => e.employeeId == employeeID);
答案 2 :(得分:0)
在IEnumerable或IQueryable上调用的任何函数都将重新执行查询...这就是为什么在循环中放置这样的东西并不好。你结束了对数据库的大量查询。至于为什么它会得到Exception我会使用.Any()而不是count来确定结果的长度
return (entityResult.Any<Employee>() > 0) ? entityResult.First<Employee>() : new EmployeeEntity();
虽然逻辑有点令人困惑,但是因为你想要返回一个EmployeeEntity,而查询建议你只想回一个。所以你可以使用
entityResult.Single<Employee>()
如果返回多个异常将抛出异常,除非您无法处理调用者中的异常。然后SingleOrDefault可能是最好的,然后检查null并且没有计数或任何检查。
只是一些建议总是有不止一种方法可以做某事