使用Fluent NHibernate自动映射的枚举的NullReferenceException映射集合

使用Fluent NHibernate自动映射的枚举的NullReferenceException映射集合,nhibernate,fluent-nhibernate,Nhibernate,Fluent Nhibernate,我有一个包含枚举集合的类,如下所示 public enum TransactionType { ... } public class PaymentMethod { ... public virtual IList<TransactionType> SupportedTransactionTypes { get; set; } } 公共枚举事务类型 { ... } 公共类支付方法 { ... 公共虚拟IList支持的TransactionTypes{get;set;}

我有一个包含枚举集合的类,如下所示

public enum TransactionType
{
  ...
}

public class PaymentMethod
{
  ...
  public virtual IList<TransactionType> SupportedTransactionTypes { get; set; }
}
公共枚举事务类型
{
...
}
公共类支付方法
{
...
公共虚拟IList支持的TransactionTypes{get;set;}
}
对TransactionType枚举的其他引用工作正常,但对于此集合,我遇到一个异常:“NHibernate.MappingException:关联引用未映射的类:mynamespace.TransactionType”

环顾四周,我似乎需要指定元素映射的类型,即一对多、元素或复合元素

我已为PaymentMethod类设置了以下覆盖映射:

mapping.HasMany(x => x.TransactionTypes)
  .Element("TransactionTypeId"), x => x.Type<TransactionType>());
mapping.HasMany(x=>x.TransactionTypes)
.Element(“TransactionTypeId”),x=>x.Type();
但这会导致以下异常

验证失败:System.NullReferenceException:对象引用未设置为对象的实例。 在FluentNHibernate.Conventions.Inspections.OneToManyInspector.get_Class()中的e:\horn.horn\orm\FluentNHibernate\Working\src\FluentNHibernate\Conventions\Inspections\OneToManyInspector.cs:第40行 在e:\horn.horn\orm\FluentNHibernate\Working\src\FluentNHibernate\Conventions\ProxyConvention.cs中的FluentNHibernate.Conventions.ProxyConvention.Apply(ICollectionInstance实例):第79行 在FluentNHibernate.Visitors.ConventionVisitor.Apply[TInspector,TInstance](IEnumerable conventions,TInstance实例)中的e:\horn.horn\orm\FluentNHibernate\Working\src\FluentNHibernate\Visitors\ConventionVisitor.cs:第269行 在

我尝试了很多不同的映射变体,包括TableName、KeyColumn和我能想到的任何其他东西,但是我无法让这个映射工作


感谢您的帮助……

我认为您无法映射枚举集合。您肯定不能在大约一年前将集合作为管道分隔字符串保存在数据库中

    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()); }
    }
为了更新备份字段,您需要使用helper方法来添加/删除枚举,而不是使用集合本身上的方法

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

希望这能有所帮助。

也许这是FluentNHibernate最近的一个修复程序,但它适用于FluentNH v1.2.0.712。我非常确信,具有普通*.hbm.xml映射的NHibernate多年来一直支持这种类型的映射

这是对我有效的自动映射覆盖:

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>
。。。这正是我所期望的。是的,尼伯内特

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