2011-12-01 22 views
5

Bir NHServer 2008 veritabanında zaman damgası sütununu, NHibernate'in yeni kod tabanlı eşleştirmelerini kullanarak eşlemek için doğru yol nedir? (NHibernate 3.2 Kod Yazarak Mülkün Sınıflandırması

Version(x => x.RowVersion, mapping => 
    mapping.Generated(VersionGeneration.Always)); 

Ancak NHibernate bu haritaya dayanan bir tamsayı bekliyor bir atar:

benim sınıfta mülkiyet byte [] olarak tanımlanır ve benim ClassMapping dosyasında aşağıdaki eşleme kullanıyorum var eklerdeki istisna). Açık olarak eşleme türünü byte [] olarak belirtirseniz, "System.ArgumentOutOfRangeException: IUserVersionType Parametre adı: persistentType" parametresini uygulayarak beklenen türden bir özel durum alırım.

Otomatik güncelleştirme zaman damgası sütunu yeni NHibernate kod tabanlı eşlemlerle eşleştirmenin uygun yolu nedir?

--- DÜZENLEME

ben ben BinaryType (IVersionType uygulayan bir NHibernate Tipi) haritalama üzerine Type ayarlamak gerektiğini daralmış var, ama BinaryType bir public kurucu yoktur. ..Sanırım fikrim yok.

cevap

4

Ayrıca, sürüm uygulaması için byte[] Version { get; } kullanıyoruz.

fazla ayrıntı için de
Version(x => x.Version) 
      .Nullable() 
      .CustomSqlType("timestamp") 
      .Generated.Always() 
      ; 

Eğer NHib kaynak kodunu kapmak varsa, gerekenler ile yardımcı olacak bir deney projesinde bir sınıf var this link

+0

Cevabınız için teşekkürler, ne yazık ki Fluent Nhibernate kullanmıyorum. Ben sadece 3.2 içinde yeni inşa edilmiş kod eşlemeleri kullanıyorum Yerleşik by-code eşleştirmeler bir CustomSqlType yok – wllmsaccnt

5

bakın: Burada

dışarı eşleştirmeleri olduğunu : NHibernate.Test.VersionTest.Db.MsSQL.BinaryTimestamp. Temel olarak, değeri dönüştürmek için kullanabileceği özel bir tür vermelisiniz. Varsayılan NHib, değerin bir int olmasını bekler ( the nhib docs'un 5.1.7 numaralı bölümüne bakın). Sürüm sütununuz olarak bir int/bigint kullanırsanız, özel bir türe ihtiyacınız olmayacaktır. (NHib kaynak kodundan kaldırıldı)

özel bir sınıf:

public class BinaryTimestamp : IUserVersionType 
{ 
    #region IUserVersionType Members 

    public object Next(object current, ISessionImplementor session) 
    { 
     return current; 
    } 

    public object Seed(ISessionImplementor session) 
    { 
     return new byte[8]; 
    } 

    public object Assemble(object cached, object owner) 
    { 
     return DeepCopy(cached); 
    } 

    public object DeepCopy(object value) 
    { 
     return value; 
    } 

    public object Disassemble(object value) 
    { 
     return DeepCopy(value); 
    } 

    public int GetHashCode(object x) 
    { 
     return x.GetHashCode(); 
    } 

    public bool IsMutable 
    { 
     get { return false; } 
    } 

    public object NullSafeGet(IDataReader rs, string[] names, object owner) 
    { 
     return rs.GetValue(rs.GetOrdinal(names[0])); 
    } 

    public void NullSafeSet(IDbCommand cmd, object value, int index) 
    { 
     NHibernateUtil.Binary.NullSafeSet(cmd, value, index); 
    } 

    public object Replace(object original, object target, object owner) 
    { 
     return original; 
    } 

    public System.Type ReturnedType 
    { 
     get { return typeof(byte[]); } 
    } 

    public SqlType[] SqlTypes 
    { 
     get { return new[] { new SqlType(DbType.Binary, 8) }; } 
    } 

    public int Compare(object x, object y) 
    { 
     var xbytes = (byte[])x; 
     var ybytes = (byte[])y; 
     return CompareValues(xbytes, ybytes); 
    } 

    bool IUserType.Equals(object x, object y) 
    { 
     return (x == y); 
    } 

    #endregion 

    private static int CompareValues(byte[] x, byte[] y) 
    { 
     if (x.Length < y.Length) 
     { 
      return -1; 
     } 
     if (x.Length > y.Length) 
     { 
      return 1; 
     } 
     for (int i = 0; i < x.Length; i++) 
     { 
      if (x[i] < y[i]) 
      { 
       return -1; 
      } 
      if (x[i] > y[i]) 
      { 
       return 1; 
      } 
     } 
     return 0; 
    } 

    public static bool Equals(byte[] x, byte[] y) 
    { 
     return CompareValues(x, y) == 0; 
    } 
} 

bu sınıfı kullanılarak örnek bir eşleme: Aşağıdaki kullanarak sona bir ConventionModelMapper halinde

public class Car 
{ 
    public virtual long CarId { get; set; } 
    public virtual string Name { get; set; } 
    public virtual byte[] LastModified { get; set; } 

    public override string ToString() 
    { 
     return string.Format("Id: {0}, Name: {1}, Last Modified: {2}", CarId, Name, LastModified); 
    } 
} 

public class CarMap : ClassMapping<Car> 
{ 
    public CarMap() 
    { 
     Table("Cars"); 

     Id(car => car.CarId, mapper => mapper.Generator(Generators.Identity)); 
     Property(car => car.Name); 
     Version(car => car.LastModified, mapper => 
              { 
               mapper.Generated(VersionGeneration.Always); 
               mapper.Type<BinaryTimestamp>(); 
              }); 
    } 
} 
3

..

ConventionModelMapper mapper = new ConventionModelMapper(); 

//...other mappings 

mapper.Class<Entity>(map => map.Version(e => e.Revision, m => 
       { 
        m.Generated(VersionGeneration.Always); 
        m.UnsavedValue(null); 
        m.Type(new BinaryBlobType()); 
        m.Column(c => 
         { 
          c.SqlType("timestamp"); 
          c.NotNullable(false); 
         }); 
       }));