So v2 is going to have to happen at some point; we will want to do as much as we can at one "break", so: thoughts here:
IDbConnection
etc to DbConnection
for the async methodsCancellationToken
is used on all async methodsnetstandard1.3
SqlClient
dependency (need to fix one API only)IAsyncEnumerable<T>
APIIDbConnection
etc to DbConnection
throughoutTask<T>
to ValueTask<T>
throughoutQueryAsync<T>
API to IAsyncEnumerable<T>
(was Task<IEnumerable<T>>
)netcoreapp3.0
and review what we can exploitPooledAwait
](https://github.com/mgravell/PooledAwait) (internal implementation detail, but adds a dependency; works best with ValueTask<T>
, but can have benefits on Task<T>
too)other ideas?
heh, turns out we've already started this here - but: always good to get another round of input!
Feels like there might be some value in keeping a QueryAsync<T>
(or equivalent) that returns Task<IEnumerable<T>>
. The case of "I don't want to block on the query, but I don't want to proceed until I've got all the results" (as compared to "I don't want to block, but can proceed once the first row is available") doesn't seem un(reasonble|common). It _kind_ of maps to buffered/not-buffered, but I don't know that that would make sense as a separate set of methods rather than the parameter it is now.
I, of course, am tempted to want the MarkedSqlString
-stuff added (opt-in, naturally) since it's so damn useful. Don't know if there's a clean way to do that though, the SO impl probably has some MS SQL Server assumptions.
That's actually very relevant, @kevin-montrose - because we could also take the opportunity to clarify buffered Vs non-buffered. Buffered => List<T>
/ ValueTask<List<T>>
, non-buffered => I[Async]Enumerable<T>
There are many times where my method's return type is Task<ImmutableArray<Foo>>
and I don't want to buffer to a List<Foo>
since I have to do .ToImmutableArray()
myself anyway. It would be cool if somehow the immutable array builder could be the buffer itself.
@jnm2 we'd still have a non-buffered API - it would just be more explicit in the naming; in your case, you'd presumably just write an extension method that wraps that up for you?
That sounds good.
Don't know if it's the correct place, but not having the TypeMapper a singleton would be very helpful. The current behavior doesn't allow your application to be connected to two different databases at the same time.
Maybe attach these TypeMappers on the DbConnection ?
Thanks
@vdaron valid observation, but not quite sure what that would look like in terms of usage; presumably we'd need some kind of config state, so is that an argument? or a source? i.e. is it
```c#
var data = connection.Query
or is it:
```c#
var data = config.Query<T>(connection, "...", ... );
or is it something else? I think that's a valid discussion, but probably one to split out separately. If there is a case to add it as a parameter, for example, that would be better done "sooner" than "later".
In terms of usage, I would prefer the first one.
One other option would be to have a DapperConnection inheriting from IDbConnection and encapsulating a DbConnection , but it's probably a little too much :-)
One other option would be to have a DapperConnection inheriting from IDbConnection and encapsulating a DbConnection
My concern there is that a lot of apps allocate lots of connections, which makes that - well, not impossible, but perhaps undesirable.
Most helpful comment
Don't know if it's the correct place, but not having the TypeMapper a singleton would be very helpful. The current behavior doesn't allow your application to be connected to two different databases at the same time.
Maybe attach these TypeMappers on the DbConnection ?
Thanks