Invalid return value for general argument

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.

Dynamic parameters

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; 
+5
source share
1 answer

If DBNull is a valid value and should mean something other than the default value (TKey) (ex: default (int) = 0), and if TKey will always be a value type, then restrict TKey as a structure as follows:

 public async Task<TKey?> SaveAsync<TKey>(IGraph builder, IDataContext context = null) where TKey : struct { ... } 

Then enter the key like this:

 TKey? returnedId = parameters.Get<TKey?>(key.ResolvedName); 

The return type of SaveAsync will indicate that the key may be null. If the key should never be empty, and if DBNull should be set by default (TKey), simply use the following:

 public async Task<TKey?> SaveAsync<TKey>(IGraph builder, IDataContext context = null) where TKey : struct { ... return parameters.Get<TKey?>(key.ResolvedName).GetValueOrDefault(); } 
+1
source

All Articles