5

Ich habe folgenden Aufzählungstyp:Warum ignoriert AutoMapping von Fluents NHibernate einen Aufzählungstyp?

public enum EnumType 
{ 
    E1, 
    E2 
} 

in der folgenden Klasse verwendet:

public class X 
{ 
    public virtual int? Id { get; set; } 

    public virtual EnumType EnumProperty { get; set; } 

    public virtual string S { get; set; } 
} 

Ich mag mit NHibernate in einer Datenbankinstanz dieser Art bestehen bleiben. Und vorformulierten Schreiben von Code zu vermeiden, ich versuche Auto-Mapping-Funktion wie folgt zu verwenden:

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(); 
} 

wo MyAutoMappingConfiguration wie folgt aussieht:

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"; 
    } 
} 

Wenn ich das aus dieser Konfiguration generierte Schema zum Erstellen die Datenbank:

new SchemaExport(this.sessionProvider.NHibernateConfiguration) 
    .Execute(true, true, false); 

das folgende Skript wird generiert und ausgeführt:

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) 
) 

Warum wird die Eigenschaft EnumProperty ignoriert?

Wenn ich füge eine explizite Abbildung für X, oder (was scheint gleichwertig) eine Überschreibung für Auto-Mapping wie folgt aus:

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

das Skript korrekt generiert wird:

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) 
) 

Dies zeigt, dass es scheint nichts falsch mit NHibernate die Fähigkeit zu sein, die präsentiert enum korrekt abzubilden. Warum kann Auto-Mapping damit nicht umgehen?


Wenn ich die folgende Methode MyAutoMappingConfiguration hinzufügen:

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

und legen Sie den Haltepunkt ist die resulttrue für das EnumProperty Mitglied, die irgendwie später ignoriert wird.

+0

Aus bestimmten Gründen scheint es standardmäßig deaktiviert zu sein, wenn Auto-Mapping verwendet wird. https://groups.google.com/forum/#!topic/fluent-nhibernate/NJo0FiWXEwY – Najera

+0

@Najera Bitte beachten Sie meinen Kommentar unter] DeJaVo's Antwort] (http://Stackoverflow.com/a/34714996/2642204). – BartoszKP

+0

Wenn die Methode ausgeführt wird, ist leer, aber der Delegat wird ausgeführt? Wenn ja, wird Ihre Immobilie bewertet? – Najera

Antwort

2

In meiner Erfahrung sind Enums aus der Box gemeißelt, nichts extra zu tun (keine benutzerdefinierten Typen oder Komponenten).

So gibt es zwei Probleme:

  • IsComponent sollte nicht an, dass die Enum in Frage eine Komponente ist:

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

    (oder entfernen Sie einfach die Umsetzung überhaupt)

  • ShouldMap sollte nicht zeigen, dass die Aufzählungs explizit zugeordnet werden muss. Es wird trotzdem abgebildet, weil es eine Eigenschaft ist.So zum Beispiel:

    public override bool ShouldMap(Member member) 
    { 
        return base.ShouldMap(member) && member.CanWrite && 
          !member.MemberInfo.IsDefined(typeof(NotMappedAttribute), false); 
    } 
    

    In Ihrem Fall, wenn die Enumeration im gleichen Namensraum ist, sollten Sie tun:

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

    (das ist ein wenig kontraintuitiv)

+0

Es ist unklar, was ich tun soll. Sie müssen die Enum abbilden, warum sollten Sie dann "! Type.IsEnum" setzen? Sprechen Sie Mitglied oder geben Sie 'ShouldMap' ein? Fühlen Sie sich frei, die Antwort beliebig zu bearbeiten. –

+2

Ja, "map" sollte nur im Zusammenhang mit ganzen Entitäten verwendet werden, nicht deren Eigenschaften - das war das Hauptproblem bei meinem Ansatz. Ich habe deine Antwort bearbeitet, um das zu erklären - bitte repariere es, wenn du merkst, dass es nicht klar genug ist. Danke noch einmal! – BartoszKP

Verwandte Themen