zzzprojects / Dapper-Plus

Dapper Plus - High-Efficient Bulk Actions (Insert, Update, Delete, and Merge) for .NET
https://dapper-plus.net/
383 stars 85 forks source link

IDbConnectionFactory > The Provider could not be resolved. You must explicitly set the Provider #89

Closed ltond closed 3 years ago

ltond commented 3 years ago

We are seeing this error

The Provider could not be resolved. You must explicitly set the Provider.'

when trying to call DbConnection.BulkInsert using the Dapper Plus library.

DbConnection here is created via a IDbConnectionFactory - CreateConnection() method. We are bootstrapping the DbConnectionFactory as follows:

services.AddDbConnectionFactory(
    _ => new SqlConnection(Configuration.GetConnectionString("xxx")));

Exception stack trace:

   at Z.BulkOperations.BulkOperation.()
   at Z.BulkOperations.BulkOperation.Execute()
   at Z.BulkOperations.BulkOperation.BulkInsert()
   at Z.Dapper.Plus.DapperPlusAction.Execute()
   at Z.Dapper.Plus.DapperPlusActionSet`1.DapperPlusActionSetBuilder(DapperPlusContext context, IDbConnection connection, IDbTransaction transaction, String mapperKey, DapperPlusActionKind actionKind, IEnumerable`1 items, Func`2[] selectors)
   at Z.Dapper.Plus.DapperPlusActionSet`1..ctor(DapperPlusContext context, IDbConnection connection, String mapperKey, DapperPlusActionKind actionKind, IEnumerable`1 items, Func`2[] selectors)
   at Z.Dapper.Plus.DapperPlusExtensions.BulkInsert[T](IDbConnection connection, String mapperKey, IEnumerable`1 items, Func`2[] selectors)
   at Z.Dapper.Plus.DapperPlusExtensions.BulkInsert[T](IDbConnection connection, IEnumerable`1 items, Func`2[] selectors)
   at <<application code>>
JonathanMagnan commented 3 years ago

Hello @ltond ,

What's the DbConnection full name? Are you using something like MiniProfiler or your use your own custom connection?

Best Regards,

Jon

ltond commented 3 years ago

Hi @JonathanMagnan,

DbConnection.ToString():

Dapper.Logging.Hooks.WrappedConnection`1[[Dapper.Logging.Empty, Dapper.Logging, Version=0.4.3.0, Culture=neutral, PublicKeyToken=9516ed96e39666d6]]

It happens when running locally, the connection string is of the form Server=localhost;Database=...;User Id=...;Password=...;

No MiniProfiler or custom connection here.

ltond commented 3 years ago

From above it looks like we are using https://github.com/hryz/Dapper.Logging for the AddDbConnectionFactory extension method and the wrapper round the DbConnection. This was added for logging SQL queries to output - would we be better off switching to MiniProfiler?

JonathanMagnan commented 3 years ago

Hello @ltond ,

We normally "bypass" that kind of profiler. Since we need to make some reflection (we don't have any provider dependencies), trying to support all this kind of profiler would be way too hard.

So if you wish to use our library, use the real connection. For example, a SqlConnection.

You can also get easily the underlying connection using reflection of this WrappedConnection: https://github.com/hryz/Dapper.Logging/blob/ad531477ac8ecd5c1d9d3fa6de868746aad86eff/src/Dapper.Logging/Hooks/WrappedConnection.cs#L11

something like this (code has not been tested):

public static DbConnection GetInnerConnection<T>(this WrappedConnection<T> wrappedConnection)
{
    var connectionField = wrappedConnection.GetField("_connection", BindingFlags.NonPublic | BindingFlags.Instance);
    var connection = connectionField.GetValue(wrappedConnection);
    return connection;
}

Best Regards,

Jon