2015-03-19 2 views
2

Я пытаюсь использовать структуры как параметры в 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; } 
} 
+0

Работает ли оно, если вы измените поле структуры в свойство? Изменения в приведенной вами ссылке github в основном меняют код IL, чтобы использовать 'call' вместо' callvirt' в случае типов значений. Но они все еще называют 'GetGetMethod' для доступа к свойству. – Dirk

+0

@ Dirk: Да, собственность работает. Спасибо! – discrete

+0

@discrete Вы должны поместить это редактирование в ответ и пометить его как разрешенное, чтобы другие пользователи могли легко найти исправление. – CodingIntrigue

ответ

6

Проблема не связан с использованием структур, это вызвано использованием полей вместо свойств.

Если вы измените struct Simple на class Simple, все равно не будет работать, потому что считыватель параметров создает только код IL для чтения свойств.

Изменение поля ID в собственность решит его.

+0

У меня был всплеск, чтобы исправить его для работы с полями и свойствами, но в нем что-то было очень не так, и у меня не было возможности отладить его (или, скорее, повторить его); вы совершенно правы. –

Смежные вопросы