I am trying to save a model in a database using Dapper. I set the parameters with an I / O parameter, which is an int with the existing primary key value used for the update.
public async Task<TKey> SaveAsync<TKey>(IGraph builder, IDataContext context = null) { var parameters = this.GetParametersFromDefinition(builder, DefinitionDirection.In); // See if we have a key defined. If not, we assume this is a new insert. // Otherwise we pull the key out and assume it an update. PropertyDefinition key = builder.GetKey(); if (key != null) { parameters.Add(key.ResolvedName, key.PropertyValue, null, ParameterDirection.InputOutput); } else { throw new InvalidOperationException("The data graph did not have a primary key defined for it."); } await this.ExecuteProcedure(parameters, builder, context); object returnedId = parameters.Get<TKey>(key.ResolvedName); return returnedId == null ? default(TKey) : (TKey)returnedId; } private Task ExecuteProcedure(DynamicParameters parameters, IGraph builder, IDataContext context = null) { ProcedureDefinition mapping = builder.GetProcedureForOperation(ProcedureOperationType.Insert); if (string.IsNullOrEmpty(mapping.StoredProcedure)) { throw new InvalidOperationException("No stored procedure mapped to the builder."); } // Query the database return this.SetupConnection( context, (connection, transaction) => connection.ExecuteAsync( mapping.StoredProcedure, parameters, commandType: CommandType.StoredProcedure, transaction: transaction)); }
It is called as follows:
this.Address.AddressId = await repository.SaveAsync<int>(graph);
When I evaluate the parameters, I see my input / output parameters on it.

However, when I try to execute this line in my save:
TKey returnedId = parameters.Get<TKey>(key.ResolvedName);
I am given the following exception:
Exception: Caught: "Trying to apply a DBNull type to a type with a null value! Note that the out / return parameters will not be updated until the data stream completes (after" foreach "for Query (..., buffered: false ) or after the GridReader has been selected for QueryMultiple) "(System.ApplicationException) Thrown System.ApplicationException:" Trying to throw DBNull on a type with a null value! Note that the out / return parameters will not be updated until the stream data will not end (after "foreach" for Query (..., buffered: false) or after the GridReader has been configured for QueryMultiple) "Time: 10/21/2010 10:19:48 AM a: [7200]
I assume this is a problem with the fact that the generic type is not null in this case, since it is an integer. Is it because Dapper always returns NULL? I just assigned OUTPUT on the stored procedure a constant value in order to make sure that something is assigned to the output.
How can I work with dapper returning nullable, is the only way to pass it to int? how is the general type?
Update
I was able to solve this using this approach. SO will not let me post it as an answer. When the deadline expires, I will send an answer if someone else does not have the best ideas.
object returnedId = parameters.Get<TKey>(key.ResolvedName); if (returnedId == null) { return default(TKey); } return (TKey)returnedId;