Why does AutoMapping from Fluent NHibernate ignore an enumeration type?

I have the following type of enumeration:

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 save instances of this type in a database using NHibernate. And to avoid writing code to the template, I am trying to use the automatic matching function 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 as follows:

 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 created 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 EnumProperty property ignored?

When I add an explicit mapping for X or (which seems equivalent) an override for auto-mapping as follows:

 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 => xS); }); 

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 correctly display the presented enumeration. Why can't automatic matching handle this?


When I add the following method to MyAutoMappingConfiguration :

 public override bool ShouldMap(Member member) { var result = base.ShouldMap(member); return result; } 

and place a breakpoint, result is true for the EnumProperty member, which will somehow be ignored later.

+5
source share
1 answer

In my experience, enumerations are displayed out of the box, nothing extra to do at all (there are no custom types or components).

So there are two problems:

  • IsComponent should not indicate that the enumeration in question is a component:

     public override bool IsComponent(Type type) { return base.IsComponent(type); } 

    (or just remove the implementation altogether)

  • ShouldMap should not indicate that the enumeration should be displayed explicitly. It will be displayed anyway, because it is 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 enumeration is in the same namespace that you should do:

     public override bool ShouldMap(Type type) { return type.Namespace == "Domain" && !type.IsEnum; } 

    (which is a little contrary to intuition)

+2
source

Source: https://habr.com/ru/post/1240125/


All Articles