NHibernate: идентификатор не обновляется при каскадном сохранении - PullRequest
0 голосов
/ 29 июля 2011

У меня есть пара доменных объектов, которые я пытаюсь сохранить, используя функциональность Cascade.Однако, когда я добавляю дочерний элемент к родительскому и сохраняю родительский, дочерний объект не сохраняется.

Обновление: Исходная версия кода здесь не очищает сеанс, чтомог бы объяснить поведение, которое я видел.Однако этого не произошло, и я обновил код в вопросе, чтобы лучше отражать реальную ситуацию.

Вот что я делаю в своем контроллере и репозитории:

// in controller
public ActionResult AddChildToParent(int id /* of parent */, ChildInputModel input)
{
    var child = GetChildFromInputModel(input); // pseudo
    var savedchild = _repo.AddChildToParent(c, id);

    // savedchild.Id is still 0, and nothing has been saved to the database.
    return View(savedchild);
}    

// in repo
public IChild AddChildToParent(IChild c, int parentId)
{
    var parent = GetParentById(parentId);
    var child = new Child();
    c.CopyValuesTo(child); // A utility function in our library
    parent.AddChild(child);

    // These two calls might be unnessesary, but I'm keeping them here to sho
    // my current code situation
    var session = GetNHibernateSession();
    session.Save(parent);

    return child;
    // session flushes when method returns thanks to injected transactions
}

Я не вижу ошибку в своем приложении, пока я не перенаправлен на страницу редактирования и ID не равен 0, но я подтвердил в базе данных, что никакая дочерняя запись не добавлена.Я ничего не изменяю над родителем - просто добавляю потомка.

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

Это мои сущности и карты (упрощенно):

public class Parent : IParent // Interface just defines everything public
{
    public int Id { get; set; }
    public string Name { get; set; }

    private IList<Child> _children;
    public IList<Child> Children
    { 
        get 
        { return _children ?? (_children = new List<Child>()); } 
    }
    public void AddChild(Child c)
    {
         this.Children.Add(c);
         c.Parent = this;
    }
}

public class ParentMap : ClassMap<Parent>
{
    public ParentMap()
    {
        Id(p => p.Id);
        Map(p => p.Name);

        HasMany(p => p.Children).Cascade.AllDeleteOrphan().Not.LazyLoad();
    }
}

public class Child : IChild // Interface just defines everything public
{
    public int Id { get; set; }
    public string Name { get; set; }
    public Parent Parent { get; set; }
}

public class ChildMap : ClassMap<Child>
{
    public ChildMap() 
    {
        Id(c => c.Id);
        Map(c => c.Name);
        References(c => c.Parent).Not.Nullable();
    }
}

1 Ответ

0 голосов
/ 29 июля 2011

Это нормально: каскады не сохраняются сразу. Потомки получают идентификаторы после следующего сброса (что может занять время, поэтому не сбрасывайте явно после каждого вызова AddChild) или после явного сохранения потомка.

var parent = GetParentById(parentId);
var child = new Child();
c.CopyValuesTo(child); // A utility function in our library
parent.AddChild(child);

var session = GetNHibernateSession();
// no need to save the parent, since it is already in the session.
// you may optionally save the child when the id is used in the code
session.Save(child);
...