2010-04-20 5 views
2

J'ai une classe qui contient une collection d'énumération comme suit.NullReferenceException mappe de mappage d'enum avec le mappage NHibernate Fluent

public enum TransactionType 
{ 
    ... 
} 

public class PaymentMethod 
{ 
    ... 
    public virtual IList<TransactionType> SupportedTransactionTypes { get; set; } 
} 

D'autres références à l'énumération TransactionType fonctionnent correctement, mais avec cette collection je reçois une exception: "NHibernate.MappingException: Association références classe unmapped: mynamespace.TransactionType". En regardant autour de moi, il semble que je devais spécifier le type de mappage d'éléments, c'est-à-dire un-à-plusieurs, un élément ou un élément-composite.

J'ai installé les applications de remplacement suivantes pour la classe PaymentMethod:

mapping.HasMany(x => x.TransactionTypes) 
    .Element("TransactionTypeId"), x => x.Type<TransactionType>()); 

Mais ce qui provoque l'exception suivante ...

validation a échoué: System.NullReferenceException: référence d'objet non définie à une instance d'un objet. à FluentNHibernate.Conventions.Inspections.OneToManyInspector.get_Class() dans e: \ horn.horn \ orm \ fluentnhibernate \ Travailler \ src \ FluentNHibernate \ Conventions \ Inspections \ OneToManyInspector.cs: ligne 40 à FluentNHibernate.Conventions.ProxyConvention.Appliquer (Instance ICollectionInstance) dans e: \ horn.horn \ orm \ fluentnhibernate \ Travailler \ src \ FluentNHibernate \ Conventions \ ProxyConvention.cs: ligne 79 à FluentNHibernate.Visitors.ConventionVisitor.Apply [TInspector, TInstance] (conventions IEnumerable, instance TInstance) dans e: \ horn.horn \ ORM \ fluentnhibernate \ Working \ src \ FluentNHibernate \ Visiteurs \ ConventionVisitor.cs: ligne 269 à ...

J'ai essayé beaucoup de différentes variations sur la cartographie, y compris TableName , KeyColumn et tout ce que je peux penser mais je ne peux pas obtenir cette cartographie pour travailler.

Toute aide appréciée ...

Répondre

0

Je ne pense pas que vous pouvez mapper une collection de énumérations. Vous avez certainement couldnt un an il y a

1

Vous pouvez persister la collection dans la base de données sous forme de chaîne délimité par pipe ...

protected string _enumCollection = "";  
    public virtual ISet<MyEnum> EnumCollection 
    { 
     get 
     { 
      var set = new HashedSet<MyEnum>(); 

      if (string.IsNullOrEmpty(_enumString)) 
       return set; 

      _enumCollection.Split(new[] {"|"}, StringSplitOptions.None).ToList() 
       .ForEach(
        x => set.Add((MyEnum)(Int32.Parse(x))) 
       ); 
      return new HashedSet<MyEnum>(set); 
     } 
     set { _enumCollection = string.Join("|", value.Select(x => ((int)x).ToString()).ToArray()); } 
    } 

puis la carte du champ de support de chaîne:

Map(x => x.EnumCollection).CustomType(typeof(string)).Access.CamelCaseField(Prefix.Underscore); 

Vous devrez utiliser des méthodes auxiliaires pour ajouter/supprimer des énumérations plutôt que d'utiliser les méthodes de la collection elle-même afin de mettre à jour le champ de sauvegarde.

public virtual void AddEnum(MyEnum enum) 
     { 
      if (!EnumCollection.Contains(enum)) 
      { 
       var set = EnumCollection; //you need to get the collection 
       set.Add(enum); //add enum to it 
       EnumCollection= set; //then set the set again 
      } 
     } 

     public virtual void RemoveEnum(MyEnum enum) 
     { 
      if (EnumCollection.Contains(enum)) 
      { 
       var set = EnumCollection; //get collection 
       set.Remove(enum); //add enum 
       EnumCollection= set; //re-set collection 
      } 
     } 

Espérons que cela aide.

3

Il s'agit peut-être d'un correctif récent dans FluentNHibernate, mais cela fonctionne avec FluentNH v1.2.0.712. Je suis assez confiant que NHibernate avec des mappages simples * .hbm.xml a pris en charge ce type de mappage pendant des années.

C'est le remplacement de AutoMapping qui a fonctionné pour moi:

mapping.HasMany(x => x.SupportedTransactionTypes) 
    .Element("TransactionTypeId"); 

... qui se traduit par ce XML ...

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"> 
    <class xmlns="urn:nhibernate-mapping-2.2" name="so.Q2676867.PaymentMethod, so, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="`PaymentMethod`"> 
    <id access="backfield" name="Id" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> 
     <column name="Id" /> 
     <generator class="identity" /> 
    </id> 
    <bag name="SupportedTransactionTypes"> 
     <key> 
     <column name="PaymentMethod_id" /> 
     </key> 
     <element type="so.Q2676867.TransactionType, so, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"> 
     <column name="TransactionTypeId" /> 
     </element> 
    </bag> 
    </class> 
</hibernate-mapping> 

...et ces tables:

create table [PaymentMethod] (
    Id INT IDENTITY NOT NULL, 
    primary key (Id) 
) 

create table SupportedTransactionTypes (
    PaymentMethod_id INT not null, 
    TransactionTypeId INT null 
) 

alter table SupportedTransactionTypes 
    add constraint FK738E3751B597A1C 
    foreign key (PaymentMethod_id) 
    references [PaymentMethod] 

... ce qui correspond exactement à ce que j'attendrais. Yay NHibernate!

Questions connexes