I have this class that implements IUserType:
public class StringToIntType : IUserType
{
/// <summary>
/// mutable object = an object whose state CAN be modified after it is created
/// </summary>
public bool IsMutable
{
get { return false; }
}
public Type ReturnedType
{
get { return typeof(StringToIntType); }
}
public SqlType[] SqlTypes
{
get { return new[] { NHibernateUtil.String.SqlType }; }
}
public object NullSafeGet(IDataReader rs, string[] names, object owner)
{
var obj = NHibernateUtil.String.NullSafeGet(rs, names[0]);
if (obj == null) return null;
var s = (string)obj;
int i;
if (Int32.TryParse(s, out i))
return i;
return -1;
}
public void NullSafeSet(IDbCommand cmd, object value, int index)
{
if (value == null)
{
((IDataParameter)cmd.Parameters[index]).Value = DBNull.Value;
}
else
{
var i = (int)value;
((IDataParameter)cmd.Parameters[index]).Value = i.ToString();
}
}
public object DeepCopy(object value)
{
return value;
}
public object Replace(object original, object target, object owner)
{
return original;
}
public object Assemble(object cached, object owner)
{
return cached;
}
public object Disassemble(object value)
{
return value;
}
public new bool Equals(object x, object y)
{
if (ReferenceEquals(x, y)) return true;
if (x == null || y == null) return false;
return x.Equals(y);
}
public int GetHashCode(object x)
{
return x == null ? typeof(int).GetHashCode() + 473 : x.GetHashCode();
}
}
My mapping:
public BarausLangMap()
{
Table("BARAUSLANG");
Id(x => x.ula).CustomType<StringToIntType>();
Map(x => x.bezeichnung);
Map(x => x.sprache);
Map(x => x.la);
Where("la = 'SPE'");
}
My properties:
public virtual int ula { get; set; }
public virtual String bezeichnung { get; set; }
public virtual Int32? sprache { get; set; }
public virtual String la { get; set; }
Problem: When I do
var b = session.Get<BarausLang>(5);
It says
{NHibernate.TypeMismatchException: Provided id of the wrong type.
Expected: MobileServiceServer.Models.StringToIntType, got System.Int32
What is the problem? I thought nHibernate would call StringToIntType implicitely to convert from int to string and vice versa. I think that is the whole point. I thought StringToIntType was only for the mapping? How should I use it then?
You are correct, ReturnedType
should return the type that NullSafeGet will return. The example code you linked to is incorrect, ReturnedType
should return typeof(bool)
.
Also, getting the Equals method right is very important and I recommend a small change to your code:
public new bool Equals(object x, object y)
{
if (ReferenceEquals(x, y)) return true;
var xString = x as string;
var yString = y as string;
if (xString == null || yString == null) return false;
return xString.Equals(yString);
}
I MAY have found the problem:
public Type ReturnedType
above returns StringToIntType, and i THINK it should be int.
However, on:
http://lostechies.com/rayhouston/2008/03/23/mapping-strings-to-booleans-using-nhibernate-s-iusertype/
the method returns the type that implements IUserType.
Please confirm.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With