Reputation: 8951
I have domain objects in FluentNHibernate that have Id's that are of type object
that will always be int
(reasoning further below). Right now I have a SQLite back end. I want to map the Id as an auto-increment. So far I have:
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; }
}
But when the maps are being loaded it throws a FluentConfigurationException
with the message Identity type must be integral (int, long, uint, ulong)
for the User.Id
property (stack trace says it happens when I call Native
. Again, I really just want an auto-increment integer.
Reasoning for object Id
We have a business requirement to support several RDBMS's as well as MongoDB. I am already well aware that this is a bad idea, so please just focus on the question. Mongo uses ObjectId (a Guid-like somewhat consecutive value type) for it's default ID type. The idea is to hide the actual ID type (because it's data-layer dependent), but reuse the models and have two different data access implementations (Mongo & NHibernate).
Upvotes: 2
Views: 2534
Reputation: 8951
I ended up fixing this problem by doing
Id(x => x.Id).CustomType<int>()
.GeneratedBy.Custom<global::NHibernate.Id.IdentityGenerator>()
.UnsavedValue(null);
For some reason, fluent NHibernate doesn't understand that .CustomType<int>()
means that it really is an int. So I had to add the custom generator to bypass Fluent's logic.
This fixes the immediate problem, but I still need to figure out how collections & foreign keys need to work.
Upvotes: 3
Reputation: 135
Here is a different idea all together.
Instead of having one entity represent both database systems have separate entities that inherit from the same contract. This way you can program against the contract and then in your data access layer decide which entity type to save.
public interface IUser
{
dynamic Id {get;set;}
string Email {get;set;}
}
public class MongoUser : IUser{...}
public class SqlUser : IUser {...}
Anyways, just thought I would bring in a different perspective.
Upvotes: 1
Reputation: 52745
Instead of CustomType<int>
, try CustomType<NHibernate.Type.Int32Type>
If this doesn't work, you can just remove the Id property, and map it in NHibernate only. This does have a few programming issues (essentially, that you must call NHibernate to get an entity's Id) but it will work.
I'm not sure if Fluent supports this; I'm sure XML does and almost sure MappingByCode does too.
Upvotes: 0