Nhibernate 将对象id映射为int-identity
我有FluentNHibernate中的域对象,其Id类型为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.
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
:“行被另一个事务更新或删除(或者未保存的值映射不正确)”。为什么它试图更新
,而不是插入
?