NHibernate: IUserType не работает

У меня есть этот класс, который реализует 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 в строку и наоборот. Я думаю, в этом вся суть. Я думал, что StringToIntType предназначен только для сопоставления? Как я должен использовать его тогда?


person cdbeelala89    schedule 19.12.2012    source источник


Ответы (2)


Вы правы, ReturnedType должен возвращать тип, который возвращает NullSafeGet. Пример кода с которым вы связаны неверно, ReturnedType должно вернуть typeof(bool).

Кроме того, очень важно правильно использовать метод Equals, и я рекомендую небольшое изменение в вашем коде:

    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);
    }
person Jamie Ide    schedule 19.12.2012

Я МОЖЕТ найти проблему:

public Type ReturnedType

выше возвращает StringToIntType, и я ДУМАЮ, что он должен быть int.

Однако на:

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

метод возвращает тип, реализующий IUserType.

Пожалуйста, подтвердите.

person cdbeelala89    schedule 19.12.2012