Я пытаюсь использовать структуры как параметры в Dapper запросах. Это не работает для меня. Но это похоже на it should work.Dapper .NET: проблемы со структурированными параметризованными запросами
провальную пример:
struct Simple { public int ID; }
[TestMethod]
public void StructParameter()
{
int result = Db.Query<int>("select [ID] = @ID", new Simple { ID = 123 }).First();
result.Should().Be(123);
}
Рабочий пример:
[TestMethod]
public void AnonymousParameter()
{
int result = Db.Query<int>("select [ID] = @ID", new { ID = 123 }).First();
result.Should().Be(123);
}
Ошибка выброшен в первом случае:
System.Data.SqlClient.SqlException: Must declare the scalar variable "@ID".
Result StackTrace:
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
at System.Data.SqlClient.SqlDataReader.TryConsumeMetaData()
at System.Data.SqlClient.SqlDataReader.get_MetaData()
at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
at System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader(CommandBehavior behavior)
at Dapper.SqlMapper.<QueryImpl>d__11`1.MoveNext() in d:\Dev\dapper-dot-net\Dapper NET40\SqlMapper.cs:line 1553
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at Dapper.SqlMapper.Query[T](IDbConnection cnn, String sql, Object param, IDbTransaction transaction, Boolean buffered, Nullable`1 commandTimeout, Nullable`1 commandType) in d:\Dev\dapper-dot-net\Dapper NET40\SqlMapper.cs:line 1443
...
Я использую Dapper версии 1.38.
Per предложения по Dirk, свойство вместо поданных работ просто отлично:
struct Simple {
public int ID { get; set; }
}
Работает ли оно, если вы измените поле структуры в свойство? Изменения в приведенной вами ссылке github в основном меняют код IL, чтобы использовать 'call' вместо' callvirt' в случае типов значений. Но они все еще называют 'GetGetMethod' для доступа к свойству. – Dirk
@ Dirk: Да, собственность работает. Спасибо! – discrete
@discrete Вы должны поместить это редактирование в ответ и пометить его как разрешенное, чтобы другие пользователи могли легко найти исправление. – CodingIntrigue