DapperLib / DapperAOT

Build time tools in the flavor of Dapper
Other
349 stars 19 forks source link

TableValuedParameter not working #104

Open bsagal opened 7 months ago

bsagal commented 7 months ago

When running a query with a parameter object containing TVP field an exception is thrown. The same code without the [DapperAot] attribute workes as expected.

Code to reproduce:

using System.Data.Common;
using Dapper;
using Microsoft.Data.SqlClient;
using Microsoft.Data.SqlClient.Server;

var db = new SqlConnection(args[0]);

await db.BulkInsert(Enumerable.Empty<SqlDataRecord>());

public static class Utils {

    [DapperAot]
    public static Task BulkInsert(this DbConnection connection, IEnumerable<SqlDataRecord> values)
        => connection.ExecuteAsync("INSERT INTO table SELECT * FROM @values",
                                   new { values = values.AsTableValuedParameter("dbo.ValuesType") });
}

Received exception:

System.ArgumentException: No mapping exists from object type Dapper.SqlDataRecordListTVPParameter`1[[Microsoft.Data.SqlClient.Server.SqlDataRecord, Microsoft.Data.SqlClient, Version=5.0.0.0, Culture=neutral, PublicKeyToken=23ec7fc2d6eaa4a5]] to a known managed provider native type.
   at Microsoft.Data.SqlClient.MetaType.GetMetaTypeFromValue(Type dataType, Object value, Boolean inferLen, Boolean streamAllowed)
   at Microsoft.Data.SqlClient.MetaType.GetMetaTypeFromType(Type dataType)
   at Microsoft.Data.SqlClient.SqlParameter.GetMetaTypeOnly()
   at Microsoft.Data.SqlClient.SqlParameter.Validate(Int32 index, Boolean isCommandProc)
   at Microsoft.Data.SqlClient.SqlCommand.BuildParamList(TdsParser parser, SqlParameterCollection parameters, Boolean includeReturnValue)
   at Microsoft.Data.SqlClient.SqlCommand.BuildExecuteSql(CommandBehavior behavior, String commandText, SqlParameterCollection parameters, _SqlRPC& rpc)
   at Microsoft.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean isAsync, Int32 timeout, Task& task, Boolean asyncWrite, Boolean inRetry, SqlDataReader ds, Boolean describeParameterEncryptionRequest)
   at Microsoft.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry, String method)
   at Microsoft.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, Boolean sendToPipe, Int32 timeout, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry, String methodName)
   at Microsoft.Data.SqlClient.SqlCommand.BeginExecuteNonQueryInternal(CommandBehavior behavior, AsyncCallback callback, Object stateObject, Int32 timeout, Boolean inRetry, Boolean asyncWrite)
   at Microsoft.Data.SqlClient.SqlCommand.BeginExecuteNonQueryAsync(AsyncCallback callback, Object stateObject)
   at Microsoft.Data.SqlClient.SqlCommand.<>c.<InternalExecuteNonQueryAsync>b__210_0(AsyncCallback callback, Object stateObject)
   at System.Threading.Tasks.TaskFactory`1.FromAsyncImpl(Func`3 beginMethod, Func`2 endFunction, Action`1 endAction, Object state, TaskCreationOptions creationOptions)
   at Microsoft.Data.SqlClient.SqlCommand.InternalExecuteNonQueryAsync(CancellationToken cancellationToken)
--- End of stack trace from previous location ---
   at Dapper.Internal.AsyncCommandState.<ExecuteNonQueryAsync>g__Awaited|9_0(Task pending, DbCommand command, CancellationToken cancellationToken) in /_/src/Dapper.AOT/Internal/AsyncCommandState.cs:line 112
   at Dapper.Command`1.ExecuteAsync(TArgs args, CancellationToken cancellationToken) in /_/src/Dapper.AOT/CommandT.Execute.cs:line 35
   at Dapper.Command`1.ExecuteAsync(TArgs args, CancellationToken cancellationToken) in /_/src/Dapper.AOT/CommandT.Execute.cs:line 41
   at Program.<Main>$(String[] args)
   at Program.<Main>(String[] args)
mgravell commented 7 months ago

Thanks. We need some additional work for this, which is already in progress but incomplete; so - yes, thanks for report - it helps prioritization; will get this landed ASAP