代码之家  ›  专栏  ›  技术社区  ›  user8128167

由于IDBasyncEnumable错误,无法使用实体框架查询数据库

  •  0
  • user8128167  · 技术社区  · 7 年前

    System.InvalidOperationException系统无效操作异常发生

    消息=源IQueryable未实现IDbAsyncEnumerable。只有实现IDbAsyncEnumerable的源才能用于实体框架异步操作。有关详细信息,请参见 http://go.microsoft.com/fwlink/?LinkId=287068

    源=实体框架

    堆栈跟踪: 1 source)
    at System.Data.Entity.QueryableExtensions.ToListAsync[TSource](IQueryable
    1个来源)
    在C:\ Projects\MyApp\MyApp Model\Cpr.Apps.Tam.Model\Utilities\DataSnapshot.cs:line 160中的Cpr.Apps.Tam.Model.Utilities.Utilities.Utilities.DataSnapshot`1.d|u18.MoveNext()

    内部异常:

    所以我尝试使用这个代码(参见 @Tony O'Hagan's 回答 IDbAsyncEnumerable not implemented ,从他引用的页面来看, 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未处理消息=对象引用未设置为对象的实例。


    at lambda_方法(关闭,缺陷总结)
    在System.Linq.Enumerable.WhereListIterator 1.MoveNext()
    at System.Linq.Enumerable.<DistinctIterator>d__64
    1.移动下一个()
    在System.Linq.Buffer 1..ctor(IEnumerable 1个来源)
    在System.Linq.OrderedEnumerable 1.<GetEnumerator>d__1.MoveNext()
    at System.Linq.Enumerable.<DistinctIterator>d__64
    1.移动下一个()
    在System.Linq.Enumerable.dúu 25 1.MoveNext()
    at MyApp.Model.Utilities.DbAsyncEnumerator
    1.将MoveNextAsync(CancellationToken CancellationToken)放在C:\ Projects\MyApp\Model\Utilities\AsyncQueryableExtensions.cs:line 125中
    在System.Data.Entity.Infrastructure.IDbAsyncEnumerableExtensions.d|u 5`1.MoveNext()内部异常:

    有人建议我如何找到导致异常的空值吗?它发生在这个函数中:

        public Task<bool> MoveNextAsync(CancellationToken cancellationToken)
        {
            return Task.FromResult(_inner.MoveNext());
        }
    

    当我检查内部时,不清楚变量的哪个部分导致了空错误:

    -       _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:

    谢谢你的建议, @Ivan Stoev StartPoint/EndPoint ,而且它没有错误,所以我不确定这是为什么。可能是Visual Studio中缓存了某些内容?

    1 回复  |  直到 7 年前
        1
  •  0
  •   user8128167    7 年前

    通过不使用存储过程结果来解决该问题,存储过程结果将创建 GetDefect_Result Defect 上面的MVVM应用程序要使用的类型 foreach 键入结果。此解决方案还涉及删除对 IDbAsyncEnumerable .

        public IQueryable<Defect> GetLoadQuery()
        {
            IDbSet<Defect> dbSet = DbContext.Defects;
    
            IQueryable<Defect> query = dbSet.AsQueryable();
    
            // Other code here for filtering results...
            return query;
        }