为什么没有 DbSet.ToIEnumerableAsync()?

huangapple go评论56阅读模式
英文:

Why is there no DbSet.ToIEnumerableAsync()

问题

To ensure I understand this correctly, if you have the following code:

DbContext context;
DbSet<User> Users;

// This line creates an Expression object, but there is no call to the database
var expr = context.Users.Select().Where().OrderBy();

现在,如果需要获取该表达式返回的枚举,然后调用:

// 这将启动与数据库的查询。
var list = await context.Users.Select().Where().OrderBy().ToListAsync();

现在上面的代码正在启动一个查询并返回,允许代码继续执行,而查询会在后台完成。如果我只需要一个IEnumerable,那我会使用ToIEnumerableAsync()而不是ToListAsync()。但为什么没有ToIEnumerableAsync()呢?是因为对于异步查询,它需要明确的方式来加载返回的数据吗?

另外一个相关的问题是,我可以编写以下代码:

foreach (var item in context.Users.Select().Where().OrderBy())

这段代码有效,因为Expression实现了IEnumerable。为了确认,这种情况下,当foreach开始执行时,它会在该表达式上调用Enumerable(),这时它会进行同步调用数据库,是吗?

这对我的编程没有问题,甚至不是问题,但我很好奇。

英文:

To make sure I understand this correctly, if I have the following:

    DbContext context;
    DbSet&lt;User&gt; Users;
    
    // This line creates an Expression object, but there is no call to the database
    var expr = context.Users.Select().Where().OrderBy();

Now if I need to get an enumeration of what is returned by that expression, then I call:

    // this will kick off a query against the DB.
    var list = await context.Users.Select().Where().OrderBy().ToListAsync();

Now the above code is starting a query and returning to allow the code to continue while the query completes. Now if what I want is a list, this is perfect.

But here's my question. If all I need is an IEnumerable, then I would use ToIEnumerableAsync() instead of ToListAsync(). Except that does not exist. Why? Is it that for an async query it needs something explicit to load the returned data into?

And an associated question. I can write the following:

foreach (var item in context.Users.Select().Where().OrderBy())

This works because an Expression implements IEnumerable. To confirm, in this case, when the foreach starts executing, it calls Enumerable() on that expression and at that point, it now makes a synchronous call to the DB - correct?

This is not a problem or even an issue for my programming. But I'm curious.

答案1

得分: 0

EF Core支持IAsyncEnumerable,如果您希望以流的方式获取结果,而不是使用ToListAsyncToArrayAsync将集合在内存中实体化。

var list = (IAsyncEnumerable<User>) context.Users.Select().Where().OrderBy();

然后,您可以遍历结果:

await foreach(var user in list)
{
    // ...
}

或者在不首先将它们加载到内存中的情况下从查询中yield结果。如果使用异步枚举器时要将数据传递给某些流提供程序,EF中可能存在一些限制,建议在使用异步枚举器时确保未启用延迟加载。

英文:

EF Core supports IAsyncEnumerable if you want to stream the results rather than materialize the set in memory with ToListAsync or ToArrayAsync.

var list = (IAsyncEnumerable&lt;User&gt;) context.Users.Select().Where().OrderBy();

From there you can iterate over the results:

await foreach(var user in list)
{
    ...
}

or yield results from a query without first loading them into memory. This does appear to have some limitations in EF if handing off to some streaming providers where the recommendation is to ensure that lazy loading is not enabled if using async enumerators.

huangapple
  • 本文由 发表于 2023年4月17日 00:24:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/76028978.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定