gpt4 book ai didi

c# - 通过IQueryable批量枚举

转载 作者:太空宇宙 更新时间:2023-11-03 15:00:11 25 4
gpt4 key购买 nike

我正在使用 Entity Framework Core 创建 IQueryable。我想找到一种方法来一次获取一页结果(比如一次 10 个结果),然后将其公开为 IEnumerable(或类似 IObservable 的东西)。我还想确保这尽可能节省内存,换句话说,如果页面大小为 10,则内存中一次只有 10 个实体。最后,我希望数据库调用是异步的,这让这变得更加困难。

这是一些伪代码,其中“ToPagingEnumerable”是我想从另一个库创建或使用的方法:

IQueryable<T> query = dbContext.SomeTable;
IEnumerable<T> results = query.ToPagingEnumerable(pageSize: 10);
ConvertAndSaveResults(results);

这是一个快速失败的尝试,它不会起作用,因为您不能将“yield”与“async”结合使用:

public static IEnumerable<TSource> ToPagingEnumerable<TSource>(
this IQueryable<TSource> source,
int size)
{
var skip = 0;
var cached = await source.Take(size).ToListAsync();
while (cached.Any())
{
foreach (var item in cached)
{
yield return item;
}
skip += cached.Count;
cached = await source.Skip(skip).Take(size).ToListAsync();
}
}

我简要地查看了 Reactive Streams ( https://github.com/reactive-streams/reactive-streams-dotnet ),这似乎与我想要完成的类似。

我认为另一种选择是使用 Rx(响应式)并创建一个 Observable,它从 IQueryable 中获取一页结果(比如 10 行),将它们提供给订阅者,然后获取另一页(比如另外 10 行),并将它们提供给订阅者。

我只是对这些库中的任何一个都不太了解,不知道如何使用它们来实现我的目标,或者是否有更简单或不同的方法。

最佳答案

你好,你可以使用这个扩展方法

public static class QuerableExtensions
{
public static IQueryable<TEntity> ToPage<TEntity>(this IQueryable<TEntity> query, PagingSettings pagingSettings) where TEntity : class
{
if (pagingSettings != null)
{
return query.Skip((pagingSettings.PageNumber - 1)*pagingSettings.PageSize).Take(pagingSettings.PageSize);
}
return query;
}
public static IQueryable<T> OrderByField<T>(this IQueryable<T> query, SortingSettings sortingSettings)
{
var exp = PropertyGetterExpression<T>(sortingSettings);

var method = sortingSettings.SortOrder.Equals(SortOrder.Asc) ? "OrderBy" : "OrderByDescending";

var types = new[] { query.ElementType, exp.Body.Type };

var callExpression = Expression.Call(typeof(Queryable), method, types, query.Expression, exp);
return query.Provider.CreateQuery<T>(callExpression);
}


}

在哪里

    public class PagingSettings
{
public PagingSettings()
: this(50, 1)
{ }

protected PagingSettings(int pageSize, int pageNumber)
{
PageSize = pageSize;
PageNumber = pageNumber;
}

public int PageNumber { get; set; }
public int PageSize { get; set; }
}

要像这样使用它,你必须在进行分页之前订购你的设备

     public async Task<SimplePagedResult<TEntityDto>> GetAllPagedAsync<TEntityDto>(PagingSettins request) where TEntityDto : class
{
var projectTo = Set(); // Here is DBSet<TEnitity>


var entityDtos = projectTo.OrderByField(new SortingSettings());

if (request.PagingSettings != null)
entityDtos = entityDtos.ToPage(request.PagingSettings);

var resultItems = await entityDtos.ToListAsync();

var result = MakeSimplePagedResult(request.PagingSettings, resultItems);
return result;
}

结果类是

    public class SimplePagedResult<T>
{
public IEnumerable<T> Results { get; set; }
public int CurrentPage { get; set; }
public int PageSize { get; set; }
}

关于c# - 通过IQueryable批量枚举,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46591681/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com