2012-12-19 19 views
6

Tôi có lớp này mà thực hiện IUserType:NHibernate: IUserType không làm việc

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(); 
     } 
    } 

lập bản đồ của tôi:

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

tính của tôi:

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

Vấn đề: Khi tôi làm

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

Nó nói

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

vấn đề là gì? Tôi nghĩ nHibernate sẽ gọi StringToIntType ngầm để chuyển đổi từ int thành chuỗi và ngược lại. Tôi nghĩ đó là toàn bộ vấn đề. Tôi nghĩ StringToIntType chỉ dành cho ánh xạ? Làm thế nào tôi nên sử dụng nó sau đó?

Trả lời

5

Bạn chính xác, ReturnedType phải trả lại loại mà NullSafeGet sẽ trả lại. Mã ví dụ you linked to không chính xác, ReturnedType phải trả lại typeof(bool).

Ngoài ra, nhận được phương pháp Equals đúng là rất quan trọng và tôi khuyên bạn nên một sự thay đổi nhỏ cho mã của bạn:

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