C# NHibernate 3.2版本属性的代码类映射
使用NHibernate新的基于代码的映射,在SQL Server 2008数据库中映射时间戳列的正确方法是什么 我将类中的属性定义为byte[],并在类映射文件中使用以下映射:C# NHibernate 3.2版本属性的代码类映射,c#,.net,nhibernate,timestamp,version,C#,.net,Nhibernate,Timestamp,Version,使用NHibernate新的基于代码的映射,在SQL Server 2008数据库中映射时间戳列的正确方法是什么 我将类中的属性定义为byte[],并在类映射文件中使用以下映射: Version(x => x.RowVersion, mapping => mapping.Generated(VersionGeneration.Always)); 但是,NHibernate需要基于此映射的整数(在插入时引发异常)。如果我显式地将映射类型指定为byte[],我会得到一个异常:“S
Version(x => x.RowVersion, mapping =>
mapping.Generated(VersionGeneration.Always));
但是,NHibernate需要基于此映射的整数(在插入时引发异常)。如果我显式地将映射类型指定为byte[],我会得到一个异常:“System.ArgumentOutOfRangeException:实现IUServersOnType的预期类型
参数名称:persistentType”
使用新的基于NHibernate代码的映射映射自动更新时间戳列的正确方法是什么
---编辑
我想我已经缩小了范围,需要在映射到BinaryType(一种实现IVersionType的NHibernate类型)时设置类型,但是BinaryType没有公共构造函数……我想我已经没有主意了。我们也在使用
字节[]版本{get;}
来实现版本
下面是一些映射:
Version(x => x.Version)
.Nullable()
.CustomSqlType("timestamp")
.Generated.Always()
;
另外,有关更多详细信息,请参见如果您获取了NHib源代码,测试项目中有一个类将帮助您完成所需内容:NHibernate.test.VersionTest.Db.MsSQL.binarytimstamp。基本上,您必须给它一个自定义类型,它可以用来转换值。默认情况下,NHib希望该值为int(参见第5.1.7节)。如果使用int/bigint作为版本列,则不需要自定义类型 自定义类(摘自NHib源代码):
公共类二进制时间戳:IUServersOnType
{
#区域IUServersOnType成员
下一个公共对象(对象当前,ISessionImplementor会话)
{
回流;
}
公共对象种子(ISessionImplementor会话)
{
返回新字节[8];
}
公共对象集合(对象缓存,对象所有者)
{
返回DeepCopy(缓存);
}
公共对象深度复制(对象值)
{
返回值;
}
公共对象(对象值)
{
返回DeepCopy(值);
}
公共int GetHashCode(对象x)
{
返回x.GetHashCode();
}
公共布尔可换
{
获取{return false;}
}
公共对象NullSafeGet(IDataReader rs,字符串[]名称,对象所有者)
{
返回rs.GetValue(rs.GetOrdinal(名称[0]);
}
public void NullSafeSet(IDbCommand cmd,对象值,int索引)
{
NHibernateUtil.Binary.NullSafeSet(cmd,value,index);
}
公共对象替换(对象原始、对象目标、对象所有者)
{
归还原件;
}
公共系统。类型返回类型
{
获取{return typeof(byte[]);}
}
公共SqlType[]SqlTypes
{
获取{returnnew[]{newsqltype(DbType.Binary,8)};}
}
公共整数比较(对象x、对象y)
{
变量xbytes=(字节[])x;
var ybytes=(字节[])y;
返回比较值(xbytes,ybytes);
}
布尔IUserType.Equals(对象x,对象y)
{
返回(x==y);
}
#端区
专用静态整数比较值(字节[]x,字节[]y)
{
如果(x.长度y.长度)
{
返回1;
}
对于(int i=0;iy[i])
{
返回1;
}
}
返回0;
}
公共静态布尔等于(字节[]x,字节[]y)
{
返回CompareValues(x,y)==0;
}
}
使用该类的示例映射:
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>();
});
}
}
公车
{
公共虚拟长CarId{get;set;}
公共虚拟字符串名称{get;set;}
公共虚拟字节[]LastModified{get;set;}
公共重写字符串ToString()
{
返回string.Format(“Id:{0},名称:{1},上次修改:{2}”,CarId,名称,上次修改);
}
}
公共类CarMap:类映射
{
公共CarMap()
{
表(“Cars”);
Id(car=>car.CarId,mapper=>mapper.Generator(Generators.Identity));
属性(car=>car.Name);
版本(car=>car.LastModified,映射器=>
{
mapper.Generated(VersionGeneration.Always);
Type();
});
}
}
对于ConventionModelMapper,我最终使用了以下内容
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);
});
}));
ConventionModelMapper映射器=新ConventionModelMapper();
//…其他映射
类(map=>map.Version(e=>e.Revision,m=>
{
m、 已生成(VersionGeneration.Always);
m、 未保存的值(空);
m、 类型(新的BinaryBlobType());
m、 列(c=>
{
c、 SqlType(“时间戳”);
c、 不可为空(false);
});
}));
谢谢你的回答,不幸的是我没有使用Fluent Nhibernate。我只是在使用3.2中新增的内置代码映射。内置的by代码映射没有CustomSqlType
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);
});
}));