2010-07-09 4 views
1

Я хочу иметь возможность создать родительский объект с дочерними элементами и позволить родительскому дескриптору обновлять, сохранять и удалять.Родительский - отношения ребенка в NHibernate

Мои классы карты.

ParentMap

Id(x => x.Id, "ID").GeneratedBy.Identity(); 
     Map(x => x.Name);     

     HasMany(x => x.Children) 
      .KeyColumn("ParentID") 
      .Inverse() 
      .Cascade 
      .AllDeleteOrphan() 
      .AsBag(); 

ChildMap

Id(x => x.Id, "ID").GeneratedBy.Identity(); 
Map(x => x.Name);    
Map(x => x.Value);    
References(x => x.Parent); 

Это код.

После обратной передачи я создаю нового родителя с детьми. Проблема в том, что он не будет удалять детей, но все остальное прекрасно работает и сохраняет.

Я также пробовал код ниже, но это возвращает неединичную ошибку.

var parent = repository.Get(_view.parentID); 
parent.Name = _view.Name; 
parent.Chidlren = _view.Children; 

Может ли кто-нибудь сказать мне лучший способ справиться с этим в NHibernate?

Спасибо.

ответ

2

Вы не можете переназначить дочернюю коллекцию с помощью NHibernate. NHibernate в основном «наблюдает» за дочерней коллекцией за изменения, так что он знает, как обращаться с сохранением базы данных. Если вы переназначаете дочернюю коллекцию, NHibernate теряет ссылку и больше не может отслеживать изменения. Чтобы обойти это, вы должны изменить дочернюю коллекцию, но не переназначить ее.

Как я обычно гарантирую это, я делаю сбор только с помощью частного сеттера. Затем я добавляю методы родительскому классу для изменения списка по мере необходимости.

private IList<ChildRecord> theChildCollection = new List<ChildRecord>(); 
/// <summary> 
/// The collection of child records. 
/// </summary> 
public virtual IList<ChildRecord> Children 
{ 
    get 
    { 
     return theChildCollection.ToList().AsReadOnly(); 
    } 
    private set 
    { 
     theChildCollection = value; 
    } 
} 

/// <summary> 
/// Adds a record to the child collection. 
/// </summary> 
public void Add(ChildRecord aRecord) 
{ 
    theChildCollection.Add(aRecord); 
} 

/// <summary> 
/// Removes a record from the child collection. 
/// </summary> 
public void Delete(ChildRecord aRecord) 
{ 
    theChildCollection.Remove(aRecord); 
} 
+0

Похоже, хорошее решение Я изменю свой код. Единственная проблема заключается в том, чтобы выяснить, какие дети добавлять, обновлять и удалять, когда я имею дело с двумя списками со старыми детьми (из db) и другим списком с измененными дочерними элементами (из пользовательского ввода). Знаете ли вы способ сделать это, не зацикливая списки? Спасибо. – ctb

+0

Calum - пожалуйста, добавьте это как новый вопрос. –

0

Попробуйте очистить коллекцию детей первой:

var parent = new Parent(); 
parent.Id = _view.parentID; 
parent.Name = _view.Name; 
parent.Children.Clear(); 
parent.Children = _view.Children; 

Я не уверен, что переназначение коллекции является хорошей практикой. Я рекомендую очистить коллекцию, а затем прокрутить через _view.Children и добавить каждого ребенка. Еще лучше, используйте метод расширения IEnumerable Except, чтобы определить, какие дети нужно добавлять или удалять, и обрабатывать их отдельно.

+0

Благодарим за быстрый ответ. Я пробовал выше, он возвращает исключение NotUniqueException. Есть ли у вас примеры расширения IEnumerable Except? Спасибо. – ctb