Reputation: 8959
When I try to deserialize a record containing string represented by DbString
:
class Record
{
public DbString Text {get; set;}
}
I get error
{"Invalid cast from 'System.String' to 'Dapper.DbString'."}
Am I misusing DbString in this case?
Upvotes: 0
Views: 1488
Reputation: 2329
If you need to use DbString in the read model (as described in the comments to my first answer) then you have the option of including a mapper from string to DbString - eg. define the class
public class DbStringTypeHandler : SqlMapper.TypeHandler<DbString>
{
public override DbString Parse(object value)
{
if (value == null)
return null;
var dbStringValue = value as DbString;
if (dbStringValue != null)
return dbStringValue;
var stringValue = value as string;
if (stringValue != null)
return new DbString { Value = stringValue };
throw new InvalidCastException("Invalid cast from '" + value.GetType() + "' to '" + typeof(DbString) + "'.");
}
public override void SetValue(IDbDataParameter parameter, DbString value)
{
parameter.Value = value;
}
}
and then call
SqlMapper.AddTypeHandler<DbString>(new DbStringTypeHandler());
before performing any queries.
Now the "Record" class should behave nicely as both a read model and for "writing" (ie. setting parameters).
I tested this with a SQL server connection, I think that it's the "SqlMapper" class that you need to call "AddTypeHandler" on regardless of what database you're talking to but there's a chance that you'll need to tweak this slightly depending upon provider.
Upvotes: 2
Reputation: 2329
The idea with Dapper is to translate query results into standard .net classes.
The "DbString" type is a Dapper class that is used for specifying parameter values in a particular manner, it's not something "standard .net".
So, instead of trying to second guess what types that Dapper might want to map things to, you should start with the simplest case since Dapper will very often just work.
In your case, your record should simply be
class Record
{
public string Text { get; set; }
}
Dapper will do some work to try to make sure that any sensible type conversions are handled - for example, if your database field is an int then it will happily map that to an int property on the C# type or to a long or to a short or a byte (though you run the risk of an overflow exception at runtime if casting down to a smaller data type). In summary, Dapper is good to you and tries to do the hard work of type mapping - you can generally stick to the basics (string, rather than worrying about maybe using DbString) and Dapper will sort you out!
Upvotes: 2