wll*_*cnt 5 .net c# nhibernate timestamp version
使用NHibernate基于新代码的映射在SQL Server 2008数据库中映射时间戳列的正确方法是什么?
我的类中的属性定义为byte [],我在我的ClassMapping文件中使用以下映射:
Version(x => x.RowVersion, mapping =>
mapping.Generated(VersionGeneration.Always));
Run Code Online (Sandbox Code Playgroud)
但是,NHibernate期望基于此映射的整数(在插入时抛出异常).如果我明确地将映射类型指定为byte [],我会得到一个异常,说明:"System.ArgumentOutOfRangeException:实现IUserVersionType的预期类型参数名称:persistentType".
使用基于NHibernate代码的新映射映射自动更新时间戳列的正确方法是什么?
- -编辑
我想我已经缩小了我需要将映射上的Type设置为BinaryType(实现IVersionType的NHibernate类型),但是BinaryType没有公共构造函数......我认为我没有想法.
我们也byte[] Version { get; } 用于版本实现。
这是映射:
Version(x => x.Version)
.Nullable()
.CustomSqlType("timestamp")
.Generated.Always()
;
Run Code Online (Sandbox Code Playgroud)
此外,有关更多详细信息,请参阅此链接
如果您获取NHib源代码,那么测试项目中的一个类将帮助您满足您的需求:NHibernate.Test.VersionTest.Db.MsSQL.BinaryTimestamp.基本上,您必须为其提供可用于转换值的自定义类型.默认情况下,NHib期望该值为int(请参阅nhib docs的 seciont 5.1.7 ).如果使用int/bigint作为版本列,则不需要自定义类型.
自定义类(取自NHib源代码):
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;
}
}
Run Code Online (Sandbox Code Playgroud)
使用该类的示例映射:
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>();
});
}
}
Run Code Online (Sandbox Code Playgroud)