Первоначально я получал эту ошибку:
Произошло исключение System.InvalidOperationException
HResult = -2146233079
Сообщение = Исходный IQueryable не реализует IDbAsyncEnumerable.Только источники, которые реализуют IDbAsyncEnumerable, могут использоваться для асинхронных операций Entity Framework.Для получения дополнительной информации см. http://go.microsoft.com/fwlink/?LinkId=287068.
Source = EntityFramework
StackTrace: at System.Data.Entity.QueryableExtensions.AsDbAsyncEnumerable [T] (источник IQueryable 1 source)<br>
at System.Data.Entity.QueryableExtensions.ToListAsync[TSource](IQueryable
1)
в Cpr.Apps.Tam.Model.Utilities.DataSnapshot`1.d__18.MoveNext () в C: \ Projects \ MyApp \ MyAppModel \ Cpr.Apps.Tam.Model \ Utilities \ DataSnapshot.cs: строка 160
InnerException:
Поэтому я пытаюсь использовать этот код (см. @ ответ Тони О'Хагана в IDbAsyncEnumerable не реализован , со страницы онссылка https://msdn.microsoft.com/en-us/data/dn314429#async):
Вот исходный код:
public static class AsyncQueryableExtensions
{
public static IQueryable<TElement> AsAsyncQueryable<TElement>(this IEnumerable<TElement> source)
{
return new DbAsyncEnumerable<TElement>(source);
}
public static IDbAsyncEnumerable<TElement> AsDbAsyncEnumerable<TElement>(this IEnumerable<TElement> source)
{
return new DbAsyncEnumerable<TElement>(source);
}
public static EnumerableQuery<TElement> AsAsyncEnumerableQuery<TElement>(this IEnumerable<TElement> source)
{
return new DbAsyncEnumerable<TElement>(source);
}
public static IQueryable<TElement> AsAsyncQueryable<TElement>(this Expression expression)
{
return new DbAsyncEnumerable<TElement>(expression);
}
public static IDbAsyncEnumerable<TElement> AsDbAsyncEnumerable<TElement>(this Expression expression)
{
return new DbAsyncEnumerable<TElement>(expression);
}
public static EnumerableQuery<TElement> AsAsyncEnumerableQuery<TElement>(this Expression expression)
{
return new DbAsyncEnumerable<TElement>(expression);
}
}
internal class DbAsyncQueryProvider<TEntity> : IDbAsyncQueryProvider
{
private readonly IQueryProvider _inner;
internal DbAsyncQueryProvider(IQueryProvider inner)
{
_inner = inner;
}
public IQueryable CreateQuery(Expression expression)
{
return new DbAsyncEnumerable<TEntity>(expression);
}
public IQueryable<TElement> CreateQuery<TElement>(Expression expression)
{
return new DbAsyncEnumerable<TElement>(expression);
}
public object Execute(Expression expression)
{
return _inner.Execute(expression);
}
public TResult Execute<TResult>(Expression expression)
{
return _inner.Execute<TResult>(expression);
}
public Task<object> ExecuteAsync(Expression expression, CancellationToken cancellationToken)
{
return Task.FromResult(Execute(expression));
}
public Task<TResult> ExecuteAsync<TResult>(Expression expression, CancellationToken cancellationToken)
{
return Task.FromResult(Execute<TResult>(expression));
}
}
internal class DbAsyncEnumerable<T> : EnumerableQuery<T>, IDbAsyncEnumerable<T>, IQueryable<T>
{
public DbAsyncEnumerable(IEnumerable<T> enumerable)
: base(enumerable)
{ }
public DbAsyncEnumerable(Expression expression)
: base(expression)
{ }
public IDbAsyncEnumerator<T> GetAsyncEnumerator()
{
return new DbAsyncEnumerator<T>(this.AsEnumerable().GetEnumerator());
}
IDbAsyncEnumerator IDbAsyncEnumerable.GetAsyncEnumerator()
{
return GetAsyncEnumerator();
}
IQueryProvider IQueryable.Provider
{
get { return new DbAsyncQueryProvider<T>(this); }
}
}
internal class DbAsyncEnumerator<T> : IDbAsyncEnumerator<T>
{
private readonly IEnumerator<T> _inner;
public DbAsyncEnumerator(IEnumerator<T> inner)
{
_inner = inner;
}
public void Dispose()
{
_inner.Dispose();
}
public Task<bool> MoveNextAsync(CancellationToken cancellationToken)
{
return Task.FromResult(_inner.MoveNext());
}
public T Current
{
get { return _inner.Current; }
}
object IDbAsyncEnumerator.Current
{
get { return Current; }
}
}
Обратите внимание, что я получаю следующую ошибку:
System.NullReferenceException не обработанопо коду пользователя HResult = -2147467261 Сообщение = ссылка на объект не установлена для экземпляра объекта.
Источник = анонимно размещенная сборка DynamicMethods
StackTrace:
в lambda_method (Closure, DefectSummary)
в System.Linq.Enumerable.WhereListIterator 1.MoveNext()<br>
at System.Linq.Enumerable.<DistinctIterator>d__64
1.MoveNext ()
в System.Linq.Buffer 1..ctor(IEnumerable
1 источник)
в System.Linq.OrderedEnumerable 1.<GetEnumerator>d__1.MoveNext()<br>
at System.Linq.Enumerable.<DistinctIterator>d__64
1.MoveNext ()
в System.Linq.Enumerable.d__25 1.MoveNext()<br>
at MyApp.Model.Utilities.DbAsyncEnumerator
1.MoveNextAsync (CancellationToken cancellationToken) в C: \ Projects \ MyApp \ Model \ Utilities \ AsyncQueryableExtensions.cs: строка 125
в System.Data.Entity.Infrastructure.IDbAsyncEnumerableExtensions.d__5`1.MoveNext: 10Next: 10):
Есть ли у кого-нибудь предложения, чтобы определить, как я могу найти нулевое значение, которое вызывает исключение?Это происходит в этой функции:
public Task<bool> MoveNextAsync(CancellationToken cancellationToken)
{
return Task.FromResult(_inner.MoveNext());
}
Когда я проверяю _inner, мне не ясно, какая часть переменной вызывает нулевую ошибку:
- _inner {System.Linq.Enumerable.<TakeIterator>d__25<MyApp.Model.Entities.DefectSummary>} System.Collections.Generic.IEnumerator<MyApp.Model.Entities.DefectSummary> {System.Linq.Enumerable.<TakeIterator>d__25<MyApp.Model.Entities.DefectSummary>}
+ Non-Public members
- Results View Expanding the Results View will enumerate the IEnumerable
- Data {System.Collections.ListDictionaryInternal} System.Collections.IDictionary {System.Collections.ListDictionaryInternal}
Count 0 int
IsFixedSize false bool
IsReadOnly false bool
IsSynchronized false bool
- Keys {System.Collections.ListDictionaryInternal.NodeKeyValueCollection} System.Collections.ICollection {System.Collections.ListDictionaryInternal.NodeKeyValueCollection}
+ Non-Public members
- Results View Expanding the Results View will enumerate the IEnumerable
Empty "Enumeration yielded no results" string
SyncRoot {object} object
+ Values {System.Collections.ListDictionaryInternal.NodeKeyValueCollection} System.Collections.ICollection {System.Collections.ListDictionaryInternal.NodeKeyValueCollection}
+ Non-Public members
+ Results View Expanding the Results View will enumerate the IEnumerable
HResult -2147467261 int
HelpLink null string
+ InnerException null System.Exception
Message "Object reference not set to an instance of an object." string
Source "Anonymously Hosted DynamicMethods Assembly" string
StackTrace " at lambda_method(Closure , DefectSummary )\r\n at System.Linq.Enumerable.WhereListIterator`1.MoveNext()\r\n at System.Linq.Enumerable.<DistinctIterator>d__64`1.MoveNext()\r\n at System.Linq.Buffer`1..ctor(IEnumerable`1 source)\r\n at System.Linq.OrderedEnumerable`1.<GetEnumerator>d__1.MoveNext()\r\n at System.Linq.Enumerable.<DistinctIterator>d__64`1.MoveNext()\r\n at System.Linq.Enumerable.<TakeIterator>d__25`1.MoveNext()\r\n at System.Linq.SystemCore_EnumerableDebugView`1.get_Items()" string
+ TargetSite {Boolean lambda_method(System.Runtime.CompilerServices.Closure, MyApp.Model.Entities.DefectSummary)} System.Reflection.MethodBase {System.Reflection.Emit.DynamicMethod.RTDynamicMethod}
+ Static members
+ Non-Public members
ОБНОВЛЕНИЕ:
К вашему сведению, это функция более высокого уровня, для которой настроен запрос:
public IQueryable<Defect> GetLoadQuery()
{
IQueryable<Defect> query = null;
// Call to stored procedure GetDefects
var defectList = DbContext.GetDefects(null, null).ToList();
var defects = new List<Defect>();
using (IDefectDataService dataService = ServiceLocator.Current.GetInstance<IDefectDataService>())
{
foreach (var i in defectList)
{
dataService.DefectId = i.NotificationNo;
NotificationLinearAsset notificationLam = dataService.GetNotificationLinearAsset();
decimal? startPoint = notificationLam.StartPoint;
decimal? endPoint = notificationLam.EndPoint;
defects .Add(new Defect()
{
NotificationNo = i.NotificationNo,
Priority = i.Priority,
ReportedBy = i.ReportedBy,
MeasuringDocument = i.MeasuringDocument,
AssetTypeDescription = i.AssetTypeDescription,
StartPoint = startPoint,
EndPoint = endPoint,
Description = i.Description,
AssetId = i.AssetId,
});
}
query = defectSummaries.AsQueryable();
// Other code here for filtering results...
}
return query.AsAsyncQueryable();
}
ОБНОВЛЕНИЕ 2:
Этостановится еще более странным, потому что, если я закомментирую эти две строки, запрос сработает и выдаст результаты:
//StartPoint = startPoint,
//EndPoint = endPoint,
Но когда я ставлю условную точку останова в foreach
, чтобы остановиться, если либо startPoint
или endPoint
равно нулю, отладчик никогда не останавливается.
ОБНОВЛЕНИЕ 3:
Спасибо за предложение, @ Иван Стоев .Обратите внимание, что сегодня я выполнил еще один тест, не меняя код, кроме комментария StartPoint/EndPoint
, и он работает без ошибок, поэтому я не уверен, почему это так.Возможно, что-то было кешировано в Visual Studio?