Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何对EF select结果进行异步“分页”处理_C#_.net_Entity Framework_Asynchronous_Tpl Dataflow - Fatal编程技术网

C# 如何对EF select结果进行异步“分页”处理

C# 如何对EF select结果进行异步“分页”处理,c#,.net,entity-framework,asynchronous,tpl-dataflow,C#,.net,Entity Framework,Asynchronous,Tpl Dataflow,我正在写一些东西,将记录从SQL server加载到azure队列。问题是,select结果中的项目数可能非常大,因此我希望在仍在检索数据时开始排队 我试图利用EF6异步、所有异步方法和and进行并行排队。因此,我: // This defines queue that Generator will publsh to and // QueueManager wil read from. More info: // http://msdn.mic

我正在写一些东西,将记录从SQL server加载到azure队列。问题是,select结果中的项目数可能非常大,因此我希望在仍在检索数据时开始排队

我试图利用EF6异步、所有异步方法和and进行并行排队。因此,我:

        // This defines queue that Generator will publsh to and 
        // QueueManager wil read from. More info:
        // http://msdn.microsoft.com/en-us/library/hh228601(v=vs.110).aspx
        var queue = new BufferBlock<ProcessQueueItem>();

        // Configure queue listener first
        var result = this.ReceiveAndEnqueue(queue);

        // Start generation process
        var tasks = generator.Generate(batchId);
在某个时候,在获得所有物品之前。这会让我等待,直到所有的东西都加载到内存中

所以我的问题是:当EF查询结果从一个select中“滴入”时,我如何开始使用它们?好像如果你明白我的意思,EF会在结果上运行一个“收益率”

编辑 我想我犯了一个思考错误。默认情况下,EF加载项目。所以我可以将所有结果作为IQueryable返回,但这并不意味着它们实际上是从DB加载的。然后,我将遍历它们并将它们排队

编辑2
不,这不起作用,因为我需要在Generate方法中转换数据库中的对象

好吧,这就是我的结局:

    public IEnumerable<ProcessQueueItem> Generate(Guid batchId)
    {
        var accounts = this.AccountStatusRepository.GetAccountsByBatchId(batchId.ToString());

        foreach (var accountStatuse in accounts)
        {
            yield return accountStatuse.AsProcessQueueItem(batchId);
        }
    }

存储库只返回一些DataContext.Stuff的IEnumerable。其中。。。。生成器使用extension方法将实体转换为域模型ProcessQueueItem,该实体通过yield立即发送给该方法的调用方,调用方将开始调用QueueManager以开始排队。

应使用适当的T-SQL语句完成结果分页。异步与语句的执行方式有关,而与分页或结果的形状无关。普通的老式同步SqlReader更适合逐行使用和排队结果。对于您描述的批处理操作,ORMs而不仅仅是EF是一个糟糕的选择
public void Generate(Guid someId, ITargetBlock<ProcessQueueItem> target)
    public void Generate(Guid batchId, ITargetBlock<ProcessQueueItem> target)
    {
        var accountPromise = this.AccountStatusRepository.GetAccountsByBatchId(batchId.ToString());
        accountPromise.Wait();
        var accounts = accountPromise.Result;

        // Batch configuration
        var itemCount = accounts.Count();
        var numBatches = (int)Math.Ceiling((double)itemCount / this.batchSize);
        Debug.WriteLine("Found {0} items what will be put in {1} batches of {2}", itemCount, numBatches, this.batchSize); 


        for (int i = 0; i < numBatches; i++)
        {
            var itemsToTake = Math.Min(this.batchSize, itemCount - currentIndex);
            Debug.WriteLine("Running batch - skip {0} and take {1}", currentIndex, itemsToTake);

            // Take a subset of the items and place them onto the queue
            var batch = accounts.Skip(currentIndex).Take(itemsToTake);

            // Generate a list of tasks to enqueue the items
            var taskList = new List<Task>(itemsToTake);
            taskList.AddRange(batch.Select(account => target.SendAsync(account.AsProcessQueueItem(batchId))));

            // Return the control when all tasks have been enqueued
            Task.WaitAll(taskList.ToArray());

            currentIndex = currentIndex + this.batchSize;
        } 
public Task<IEnumerable<ProcessQueueItem> Generate(Guid someId)
var result = Generate().Wait().Result;
    public IEnumerable<ProcessQueueItem> Generate(Guid batchId)
    {
        var accounts = this.AccountStatusRepository.GetAccountsByBatchId(batchId.ToString());

        foreach (var accountStatuse in accounts)
        {
            yield return accountStatuse.AsProcessQueueItem(batchId);
        }
    }