NullReferenceException отображает коллекцию enum с автоматическим сопоставлением Fluent NHibernate - PullRequest
2 голосов
/ 20 апреля 2010

У меня есть класс, содержащий следующую коллекцию перечислений.

public enum TransactionType
{
  ...
}

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

Другие ссылки на перечисление TransactionType работают правильно, но с этой коллекцией я получаю исключение: «NHibernate.MappingException: ассоциация ссылается на не сопоставленный класс: mynamespace.TransactionType».

Оглядываясь вокруг, кажется, что мне нужно было указать тип отображения элемента, то есть один-ко-многим, элемент или составной-элемент.

Я установил следующие сопоставления переопределения для класса PaymentMethod:

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

Но это вызывает следующее исключение ...

Проверка не удалась: System.NullReferenceException: ссылка на объект не установлена ​​для экземпляра объекта. в FluentNHibernate.Conventions.Inspections.OneToManyInspector.get_Class () в e: \ horn.horn \ orm \ fluentnhibernate \ Working \ src \ FluentNHibernate \ Conventions \ Inspections \ OneToManyInspector.cs: строка 40 в FluentNHibernate.Conventions.ProxyConvention.Apply (экземпляр ICollectionInstance) в e: \ horn.horn \ orm \ fluentnhibernate \ Working \ src \ FluentNHibernate \ Conventions \ ProxyConvention.cs: строка 79 в FluentNHibernate.Visitors.ConventionVisitor.Apply [TInspector, TInstance] (IEnumerable обозначений, экземпляр TInstance) в e: \ horn.horn \ orm \ fluentnhibernate \ Working \ src \ FluentNHibernate \ Посетители \ ConventionVisitor.cs: строка 269 в ...

Я пробовал множество различных вариантов сопоставления, в том числе TableName, KeyColumn и все остальное, о чем я могу думать, но я не могу заставить это сопоставление работать.

Любая помощь приветствуется ...

Ответы [ 3 ]

3 голосов
/ 07 мая 2011

Возможно, это недавнее исправление в 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]

... это именно то, что я ожидал. Yay NHibernate!

1 голос
/ 04 ноября 2010

Вы можете сохранить коллекцию в базе данных в виде строки с разделителями-пробелами ...

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

Надеюсь, это поможет.

0 голосов
/ 10 августа 2010

Я не думаю, что вы можете отобразить коллекцию перечислений. Вы, конечно, не могли год или около того назад

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...