6

我有这个实现 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();
        }
    }

我的映射:

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'");
        }

我的属性:

    public virtual int ula { get; set; }
    public virtual String bezeichnung { get; set; }
    public virtual Int32? sprache { get; set; }
    public virtual String la { get; set; }

问题:当我这样做时

var b = session.Get<BarausLang>(5);

它说

{NHibernate.TypeMismatchException: Provided id of the wrong type.
Expected: MobileServiceServer.Models.StringToIntType, got System.Int32

问题是什么?我认为 nHibernate 会隐式调用 StringToIntType 从 int 转换为 string,反之亦然。我认为这就是重点。我以为 StringToIntType 仅用于映射?那我该怎么用呢?

4

2 回答 2

5

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);
    }
于 2012-12-19T17:09:42.330 回答
1

可能发现了问题:

public Type ReturnedType

上面返回StringToIntType,我认为它应该是int。

但是,在:

http://lostechies.com/rayhouston/2008/03/23/mapping-strings-to-booleans-using-nhibernate-s-iusertype/

该方法返回实现 IUserType 的类型。

确认

于 2012-12-19T16:24:14.317 回答