我在FluentNHibernate中有域对象,其ID为object
的ID始终为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; }
}
但是当加载地图时,它会为FluentConfigurationException
属性抛出Identity type must be integral (int, long, uint, ulong)
消息User.Id
(堆栈跟踪表示当我调用Native
时会发生这种情况。 ,我真的只想要一个自动增量整数。
对象ID的推理
我们有业务需求支持多个RDBMS以及MongoDB。我已经很清楚这是一个坏主意,所以请关注这个问题。 Mongo使用ObjectId(一种类似Guid的连续值类型)作为它的默认ID类型。我们的想法是隐藏实际的ID类型(因为它依赖于数据层),但重用模型并拥有两种不同的数据访问实现(Mongo&amp; NHibernate)。
答案 0 :(得分:3)
我最后通过
解决了这个问题Id(x => x.Id).CustomType<int>()
.GeneratedBy.Custom<global::NHibernate.Id.IdentityGenerator>()
.UnsavedValue(null);
由于某种原因,流利的NHibernate不明白.CustomType<int>()
意味着它确实是一个int。所以我不得不添加自定义生成器以绕过Fluent的逻辑。
这解决了眼前的问题,但我仍然需要弄清楚如何收集&amp;外键需要工作。
答案 1 :(得分:1)
这是一个不同的想法。
不是让一个实体代表两个数据库系统,而是具有从同一个合同继承的独立实体。这样,您可以针对合同进行编程,然后在数据访问层中确定要保存的实体类型。
public interface IUser
{
dynamic Id {get;set;}
string Email {get;set;}
}
public class MongoUser : IUser{...}
public class SqlUser : IUser {...}
无论如何,只是想我会带来不同的观点。
答案 2 :(得分:0)
而不是CustomType<int>
,请尝试CustomType<NHibernate.Type.Int32Type>
如果这不起作用,您只需删除Id属性,并仅在NHibernate中映射它。这确实有一些编程问题(基本上,您必须调用NHibernate来获取实体的ID),但它会起作用。
我不确定Fluent是否支持这个;我确信XML确实可以,并且几乎可以肯定MappingByCode也是如此。