Skip to content
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

ToQueryString() and ToDbCommand() variants that accept the entire query as an argument #33181

Open
roji opened this issue Feb 27, 2024 · 5 comments

Comments

@roji
Copy link
Member

roji commented Feb 27, 2024

ToQueryString() and ToDbCommand() work on IQueryable, and so cannot be used when e.g. a reducing terminating operator is used (Max(), Min()); it's possible to chop it off, but that changes the SQL. The same limitation applies to ExecuteUpdate/Delete, which behave like other reducing terminating operator.

A solution to this could be ToQueryString()/ToDbCommand() overloads on DbContext, which would accept the entire query as an argument:

_ = context.ToQueryString(ctx => ctx.Blogs.Max());

Note the similarity with the Query() API we've discussed several times in the past, which also accepts a full query as an argument and executes it (i.e. to get all the top-level operators as a quotation rather than execution them).

Note that this would add API noise to the DbContext surface which likely only few people will actually need. Maybe there's some way to combine ToQueryString() with the aforementioned Query() API, to help out with this.

Raised by @clement911 in #33143 (comment) and #33167.

@clement911
Copy link
Contributor

It would be also useful if there was a ToDbBatchCommand() so that we can include the command as part of a DbBatch

@clement911
Copy link
Contributor

clement911 commented Feb 28, 2024

In the meantime if anyone is looking for a workaround, I managed to make it work with a small amount of code.
Basically an interceptor records commands and suppress the execution. The collected commands are then returned to the user.

See https://gist.github.com/clement911/695d7a2ef2ac2845a8090309c5d184e7

It seems to work quite well. It assumes that the sql server connector is used. Also, it's using a pre-release of Microsoft.Data.SqlClient to issue batch commands.
There are probably some gotchas that I haven't considered but it seems to work well and the performance seems quite good.
That illustrates the power of interceptors!

UPDATE 2024-02-29 Microsoft.Data.SqlClient 5.2 stable was just released so no pre-release packages are needed anymore

@ajcvickers
Copy link
Member

Note from team triage: the idea here is good; we just need a decent API.

@ajcvickers ajcvickers added this to the Backlog milestone Mar 7, 2024
@bachratyg
Copy link

This should probably have the same shape as #10879 (whatever that turns out to be) and differ only in the return type i.e. string or DbBatchCommand instead of the actual result. Just like ToQueryString/CreateDbCommand vs ToList.

@azan-n
Copy link

azan-n commented May 24, 2024

+1 for this. It will surely make rudimentary testing easier for some of our business logic that I have been meaning to move to ExecuteUpdate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants