I have the following enumeration type:
public enum EnumType
{
E1,
E2
}
used in the following class:
public class X
{
public virtual int? Id { get; set; }
public virtual EnumType EnumProperty { get; set; }
public virtual string S { get; set; }
}
I want to persist instances of this type in a database using NHibernate. And to avoid writing boilerplate code, I'm trying to use auto mapping feature as follows:
private ISessionFactory CreateSessionFactory()
{
var mappings = AutoMap
.AssemblyOf<Domain.X>(new MyAutoMappingConfiguration());
this.NHibernateConfiguration = Fluently
.Configure()
.Database(FluentNHibernate.Cfg.Db.MsSqlConfiguration.MsSql2012.ConnectionString(
b => b.FromConnectionStringWithKey("x")))
.Mappings(m => m.AutoMappings.Add(mappings))
.BuildConfiguration();
return this.NHibernateConfiguration.BuildSessionFactory();
}
where MyAutoMappingConfiguration
looks like this:
public class MyAutoMappingConfiguration: FluentNHibernate.Automapping.DefaultAutomappingConfiguration
{
public override bool ShouldMap(Type type)
{
return type.Namespace == "Domain";
}
public override bool IsComponent(Type type)
{
return type.Name == "EnumType";
}
}
When I use the schema generated from this configuration to create the database:
new SchemaExport(this.sessionProvider.NHibernateConfiguration)
.Execute(true, true, false);
the following script is being generated and executed:
if exists (select * from dbo.sysobjects where id = object_id(N'[X]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table [X]
create table [X] (
Id INT not null,
S NVARCHAR(255) null,
primary key (Id)
)
Why is the property EnumProperty
ignored?
When I add an explicit mapping for X
, or (what seems equivalent) an override for auto-mapping like this:
var mappings = AutoMap
.AssemblyOf<Domain.X>(new MyAutoMappingConfiguration())
.Override<Domain.X>(m =>
{
m.Table("X");
m.Id(x => x.Id);
m.Map(x => x.EnumProperty); // this works
m.Map(x => x.S);
});
the script is generated correctly:
if exists (select * from dbo.sysobjects where id = object_id(N'[X]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table [X]
create table [X] (
Id INT not null,
EnumProperty NVARCHAR(255) null,
S NVARCHAR(255) null,
primary key (Id)
)
This shows that there seems to be nothing wrong with NHibernate's ability to map the presented enum correctly. Why can't auto-mapping cope with this?
When I add the following method to MyAutoMappingConfiguration
:
public override bool ShouldMap(Member member)
{
var result = base.ShouldMap(member);
return result;
}
and place the breakpoint, the result
is true
for the EnumProperty
member, which somehow gets ignored later.
In my experience enums are mapped out of the box, nothing extra to do at all (no custom types or components).
So, there are two problems:
IsComponent
shouldn't indicate that the enum in question is a component:
public override bool IsComponent(Type type)
{
return base.IsComponent(type);
}
(or just remove the implementation at all)
ShouldMap
shouldn't indicate that the enum needs to be mapped explicitly. It will be mapped anyway, because it's a property. So, for example:
public override bool ShouldMap(Member member)
{
return base.ShouldMap(member) && member.CanWrite &&
!member.MemberInfo.IsDefined(typeof(NotMappedAttribute), false);
}
In your case, if the enum is in the same namespace you should do:
public override bool ShouldMap(Type type)
{
return type.Namespace == "Domain"
&& !type.IsEnum;
}
(which is a bit counter-intuitive)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With