C# NHibernate 3.2版本属性的代码类映射

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

使用NHibernate新的基于代码的映射,在SQL Server 2008数据库中映射时间戳列的正确方法是什么

我将类中的属性定义为byte[],并在类映射文件中使用以下映射:

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