-
-
Notifications
You must be signed in to change notification settings - Fork 35
Add Async Query Support #110
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Curious as to what needs to be done to get this merged (beyond updating the branch to the latest). The code seems to work well. Happy to help! |
I'm curious too - I don't remember why I didn't merge it. I think there was something weird with extensions on Probably will need to add a few more tests at minimum as I know I had some issues previously with wrapping the "Result Transformer" on the sync-path, probably have the same issue on the async-path. I'll give it a look again - maybe today - and see what is actually left. |
977d830
to
81e2302
Compare
I worked out why I didn't merge the change, it only added async support for enumerating, not for I need to manually add every async extension myself on I'll add a few big ones and add the rest ad-hoc:
Any others after that should be fairly simple PRs just following the same pattern. |
Maybe not as simple as I was hoping - the result transformer logic for async in the driver is different from sync. Specifically for sync, it uses the All in all, I basically need to make my own result transformers but that isn't actually too bad as I might end up avoiding some reflection logic. |
I spent a chunk of time yesterday trying to understand the internals of the Async support. I got as far as the ResultTransformer and I understand what you're doing with the First, but have no idea how to help implement more. Sorry.... |
No worries - I think I have a good strategy for the different methods etc now. Also learnt that the MongoDB driver doesn't support |
Note: This commit removes .NET Standard 2.0 support however that won't be the case in the future - .NET Standard 2.0 support will still exist, this was just to get some basic tests running without needing to do a ton of ifdef statements.
The consuming code no longer needs to cast to `IMongoFrameworkQueryable<TOutput>` itself
Successfully have FirstAsync working through the full async pipeline. Pretty much broke everything else though...
New MethodInfo cache for easy access during expression building. Fleshed out the ResultTransformers logic for the different enumerable handling operations. Additional tests covering First, FirstOrDefault, Single and SingleOrDefault.
Previous type detection was invalid for the type of data returned in the pipeline. This now reflects closer to what the Driver does internally.
These are simple passthrough extensions. For anything more complex, a user can go directly to the IAsyncEnumerable themselves.
ec0b25a
to
6f2369a
Compare
What is left is |
Small change suggested, discovered when building DbSet tests for MultiTenant In QueryableAsyncExtensions.cs, two spots //if (source is IMongoFrameworkQueryable)
if (source.Provider is IMongoFrameworkQueryProvider) This change allows the extensions to run on the DbSet directly. No tests broke with this change. |
Good idea @JohnCampionJr ! |
Allows async methods from the DbSet directly
Also fixes the processing extension from Single to SingleOrDefault for Sum/SumAsync
Makes all decimal types save as a real decimal rather than a string value
This helps avoid weird issues in tests while still allowing the core logic to work in normal workloads.
Current version doesn't properly calculate code coverage and the latest version is only available via MyGet May need to look into better coverage tools that are more reliable as it isn't the first time I've had to work around it.
Closes #26
Add support for async queries, specifically async versions of these:
Additionally, support
IAsyncEnumerable<T>
viaAsAsyncEnumerable
.Each item in the list above needs custom handling to inject the right expression into the MongoDB driver while also triggering the async execution path on the
MongoQueryProvider
. If you simply callAsAsyncEnumerable().FirstOrDefaultAsync()
, that will not filter the query properly and will make the DB return more than one item (as it batches items internally). Similarly, if you ranAsAsyncEnumerable().SumAsync()
, it would return all of the items from the DB and do the sum locally. Fundamentally this problem exists as there is no such thing as an async Queryable and all enumerables are performed locally.The effort involved in supporting this process makes it possible to side step the built-in result transformer logic of the MongoDB driver which is a good thing for MongoFramework as the only way to call it was via reflection (it is an internal type we need access to).
This will have full support for .NET Standard 2.0.
Original Description
This adds
IAsyncEnumerable<TOutput>
support to MongoFramework, allowing for full async/await paths.Support will likely be shaped around Ix.NET though will likely need to factor in the same issues that EF Core have had.
The ideal end result is full backwards compatibility for
IAsyncEnumerable
even where it isn't available as standard (.NET Standard 2.0). If this is not possible, async query support will be limited to .NET Standard 2.1 and above.