Странные исключения с использованием автоматического сопоставления FluentNHibernate

В моей модели предметной области есть следующие объекты. Группа (совокупный корень) содержит элементы (которые сами являются совокупными корнями), но элемент может одновременно содержаться только в одной группе. Код ниже обеспечивает это. Причина, по которой группа имеет коллекцию Items, заключается в том, что в домене есть определенные случаи, которые наиболее логично решаются путем предоставления доступа к элементам посредством группы.

Однако когда я добавляю элемент в свою группу, я получаю FatalExecutionEngineError:

Среда выполнения обнаружила фатальную ошибку. Адрес ошибки был 0x5f0b8442 в потоке 0x99c. Код ошибки - 0xc0000005. Эта ошибка может быть ошибкой в ​​CLR или в небезопасных или неподдающихся проверке частях пользовательского кода. Общие источники этой ошибки включают ошибки маршалинга пользователей для COM-взаимодействия или PInvoke, которые могут повредить стек.

Сразу после этого выдается System.ExecutionEngineException без внутреннего исключения.

ОБНОВЛЕНИЕ

Кажется, что проверка _items.Contains(item) в методе Item.AssignTo вызывает это исключение. Изначально я исключил эту проверку из примера, но теперь добавил ее. Когда я снимаю чек, я получаю IndexOutOfRangeException в заявлении _items.Add(item);.

Это моя (упрощенная) модель предметной области:

public class Group : Entity
{
    private List<Item> _items = new List<Item>();

    public virtual IEnumerable<Item> Items
    {
        get
        {
            return _items;
        }
    }

    public virtual void Assign(Item item)
    {
        if (_items.Contains(item))
        {
            throw new ArgumentException("Already assigned.", "item");
        }

        _items.Add(item);
    }
}

public class Item : Entity
{
    public virtual Group Group
    {
        get;
        protected set;
    }

    public virtual void AssignTo(Group group)
    {
        group.Assign(this);
        this.Group = group;
    }
}

Отображение FluentNHibernate переопределяет:

// AutoMapping<Group> 
mapping
    .HasMany(n => n.Documents)
    .Access.ReadOnlyPropertyThroughCamelCaseField(Prefix.Underscore)
    .Cascade.Delete()
    .Inverse();

Итак, когда я вызываю Item.AssignTo, возникает исключение. Когда я удаляю строку group.Assign(this); из Item.AssignTo, исключение не возникает. Но, конечно, в этом случае Document.Items останется пустым, пока документ не будет извлечен из репозитория позже.

Что я здесь делаю не так или не хватает?


person Sandor Drieënhuizen    schedule 09.03.2011    source источник
comment
вы можете создать автономный тестовый набор? FatalExecutionEngineErrors обычно является ошибкой среды CLR, как и сказано в описании. Убедитесь, что у вас есть все исправления. Какую версию фреймворка вы используете?   -  person Mauricio Scheffer    schedule 09.03.2011
comment
Можете ли вы войти в Item.AssignTo с помощью отладчика?   -  person Jason Freitas    schedule 09.03.2011
comment
@Mauricio: Я постараюсь сделать автономный тестовый набор как можно скорее, хорошая идея. Кстати, я использую .NET Framework 4.0. S # arpArch находится на версии v1.9, а NHibernate v3.   -  person Sandor Drieënhuizen    schedule 09.03.2011
comment
@ Джейсон: Боже, как я мог забыть об этом. Спасибо! Исключение выбрасывается в _items.Contains(item). Изначально я пропустил это утверждение. Между прочим, если я удалю этот чек, я получу IndexOutOfRangeException на _items.Add(item);.   -  person Sandor Drieënhuizen    schedule 09.03.2011
comment
Работает, если заменить IEnumerable<Item> на IList<Item>?   -  person k3b    schedule 09.03.2011
comment
@ k3b: спасибо, но это не имело значения.   -  person Sandor Drieënhuizen    schedule 09.03.2011
comment
почему вы указываете его как свойство только для чтения? Можно ли в него добавлять предметы?   -  person Vadim    schedule 09.03.2011
comment
Items - это свойство только для чтения, потому что таким образом я могу контролировать то, что входит. На самом деле, я мог бы захотеть выполнить больше проверок, например, ограничить количество элементов и т. Д. Этот подход является частью Domain Driven Design.   -  person Sandor Drieënhuizen    schedule 09.03.2011
comment
Вы переопределяете методы Hashcode или Equals? Если в них произошла ошибка, метод Contains может вызвать исключение.   -  person Jason Freitas    schedule 10.03.2011
comment
@Jason: Я не отменяю их, но S # arpArchitecture.   -  person Sandor Drieënhuizen    schedule 10.03.2011


Ответы (1)


Мальчик, мне интересно, что здесь происходит на самом деле. Я создал отдельный тестовый сценарий, чтобы воспроизвести проблему, но почему-то все прошло нормально. Пока я экспериментировал с полным проектом, я обнаружил, что изменение private List<Item> _items = new List<Item>(); на private IList<Item> _items = new List<Item>(); решило проблему!

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

person Sandor Drieënhuizen    schedule 10.03.2011