Nhibernate 将对象id映射为int-identity

Nhibernate 将对象id映射为int-identity,nhibernate,object,fluent-nhibernate,nhibernate-mapping,Nhibernate,Object,Fluent Nhibernate,Nhibernate Mapping,我有FluentNHibernate中的域对象,其Id类型为object,始终为int(下面进一步说明)。现在我有一个SQLite后端。我想将Id映射为自动增量。到目前为止,我已经: public class UserMap : ClassMap<User> { public UserMap() { Table("Users"); Id(x => x.Id).CustomType<int>().GeneratedBy.

我有FluentNHibernate中的域对象,其Id类型为
object
,始终为
int
(下面进一步说明)。现在我有一个SQLite后端。我想将Id映射为自动增量。到目前为止,我已经:

public class UserMap : ClassMap<User>
{
    public UserMap()
    {
        Table("Users");
        Id(x => x.Id).CustomType<int>().GeneratedBy.Native();
        Map(x => x.Email);
    }
}

public class User
{
    public virtual object Id { get; set; }
    public virtual string Email { get; set; }
}
公共类用户映射:类映射
{
公共用户映射()
{
表(“用户”);
Id(x=>x.Id).CustomType().GeneratedBy.Native();
Map(x=>x.Email);
}
}
公共类用户
{
公共虚拟对象Id{get;set;}
公共虚拟字符串电子邮件{get;set;}
}
但是,当加载映射时,它会抛出一个
FluentConfigurationException
,消息是
对于
User.Id
属性,标识类型必须是整数(int、long、uint、ulong)
(堆栈跟踪表明,当我调用
Native
时会发生这种情况。同样,我只想要一个自动递增的整数

对象Id的推理


我们有一个支持多个RDBMS以及MongoDB的业务需求。我已经很清楚这是一个坏主意,所以请关注这个问题。Mongo使用ObjectId(类似连续值类型的Guid)作为默认ID类型。这个想法是隐藏实际的ID类型(因为它依赖于数据层),但重复使用模型,并有两种不同的数据访问实现(Mongo和NHibernate)。

请尝试
CustomType
而不是
CustomType

如果这不起作用,您可以删除Id属性,并仅在NHibernate中映射它。这确实有一些编程问题(本质上,您必须调用NHibernate以获取实体的Id),但它会起作用


我不确定Fluent是否支持这一点;我肯定XML支持,而且几乎肯定MappingByCode也支持。

请尝试
CustomType
而不是
CustomType

如果这不起作用,您可以删除Id属性,并仅在NHibernate中映射它。这确实有一些编程问题(本质上,您必须调用NHibernate以获取实体的Id),但它会起作用


我不确定Fluent是否支持这一点;我肯定XML支持,而且几乎肯定MappingByCode也支持

两个数据库系统都有从同一个协定继承的独立实体,而不是由一个实体表示。这样,您可以根据协定进行编程,然后在数据访问层中决定要保存的实体类型

public interface IUser
{
    dynamic Id {get;set;}
    string Email {get;set;}
}

public class MongoUser : IUser{...}

public class SqlUser : IUser {...}

不管怎样,我只是觉得我会引入一个不同的视角。

这里有一个不同的想法

两个数据库系统都有从同一个协定继承的独立实体,而不是由一个实体表示。这样,您可以根据协定进行编程,然后在数据访问层中决定要保存的实体类型

public interface IUser
{
    dynamic Id {get;set;}
    string Email {get;set;}
}

public class MongoUser : IUser{...}

public class SqlUser : IUser {...}

不管怎么说,我只是想换一个角度来看问题。

我最终通过这样做解决了这个问题

Id(x => x.Id).CustomType<int>()
    .GeneratedBy.Custom<global::NHibernate.Id.IdentityGenerator>()
    .UnsavedValue(null);
Id(x=>x.Id).CustomType()
.GeneratedBy.Custom()
.UnsavedValue(空);
出于某种原因,fluent NHibernate不理解
.CustomType()
意味着它实际上是一个int。因此我不得不添加自定义生成器以绕过fluent的逻辑


这解决了眼前的问题,但我仍然需要弄清楚集合和外键需要如何工作。

我最终通过执行

Id(x => x.Id).CustomType<int>()
    .GeneratedBy.Custom<global::NHibernate.Id.IdentityGenerator>()
    .UnsavedValue(null);
Id(x=>x.Id).CustomType()
.GeneratedBy.Custom()
.UnsavedValue(空);
出于某种原因,fluent NHibernate不理解
.CustomType()
意味着它实际上是一个int。因此我不得不添加自定义生成器以绕过fluent的逻辑

这解决了眼前的问题,但我仍然需要弄清楚集合和外键需要如何工作。

你说的“删除Id属性”是什么意思?我仍然需要一个Id,但它不必有公共getter…我现在有了
Id(x=>x.Id).CustomType().GeneratedBy.Custom()
并且它正在越过上一个错误。取而代之的是获取
StaleStateException
:“行被另一个事务更新或删除(或者未保存的值映射不正确)”。为什么它试图
更新
而不是
插入
?什么是“删除Id属性”?我仍然需要一个Id,但它不必有公共getter…我现在有
Id(x=>x.Id).CustomType().GeneratedBy.Custom()
,它正在克服以前的错误。取而代之的是
StaleStateException
:“行被另一个事务更新或删除(或者未保存的值映射不正确)”。为什么它试图
更新
,而不是
插入