2010-04-20 201 views
2

我有一個包含枚舉集合的類如下。NullReferenceException映射與流利NHibernate自動映射枚舉的集合

public enum TransactionType 
{ 
    ... 
} 

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

到TRANSACTIONTYPE列舉的其它文獻都正常工作,但與此集合我得到一個異常:「NHibernate.MappingException:協會引用未映射類:mynamespace.TransactionType」。

環顧四周,我似乎需要指定元素映射的類型,即一對多元素或複合元素。

我已經安裝了付款方法類以下重寫映射:

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

但是,這將導致以下異常...

驗證失敗:System.NullReferenceException:對象引用未設置爲一個實例的一個對象。 at FluentNHibernate.Conventions.Inspections.OneToManyInspector.get_Class()in e:\ horn.horn \ orm \ fluentnhibernate \ Working \ src \ FluentNHibernate \ Conventions \ Inspections \ OneToManyInspector.cs:line 40 at FluentNHibernate.Conventions.ProxyConvention.Apply (ICollectionInstance實例)在e:\ horn.horn \ orm \ fluentnhibernate \ Working \ src \ FluentNHibernate \ Conventions \ ProxyConvention.cs中:line 79 at FluentNHibernate.Visitors.ConventionVisitor.Apply [TInspector,TInstance](IEnumerable conventions,TInstance instance )在e:\ horn.horn \ orm \ fluentnhibernate \ Working \ src \ FluentNHibernate \ Visitors \ ConventionVisitor.cs中:第269行 at ...

我試過很多不同的變體,包括TableName ,KeyColumn和其他任何我能想到的,但我不能讓這個映射工作。

任何幫助讚賞...

回答

0

我不認爲你可以映射枚舉的集合。你當然不可能在一年多前

1

你可以堅持的集合中的數據庫作爲管道分隔字符串...

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

,然後映射到的字符串支持字段:

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

您需要使用助手方法來添加/刪除枚舉,而不是使用集合本身上的方法來更新後臺字段。

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

希望這會有所幫助。

3

也許這是FluentNHibernate最近的一個修復,但是它可以和FluentNH v1.2.0.712一起使用。我相當確信NHibernate使用普通的* .hbm.xml映射多年來一直支持這種類型的映射。

這是自動映射倍率爲我工作:

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

...這將導致該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> 

...和這些表:

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] 

......這正是我所期望的。耶NHibernate!