3

Я хочу быть в состоянии сделать следующее:Fluent NHibernate отображения, сохраняющие в обоих направлениях

var child = new Child { 
    Name = "foo", 
    Parent = new Parent { Name = "bar" } 
}; 

session.Save(child); 

ИЛИ

var parent = new Parent { 
    Name = "foo", 
    Children = new List<Child> { 
    new Child { Name = "bar" }, 
    new Child { Name = "baz" }, 
    }, 
}; 

session.Save(parent); 

и иметь его в обоих случаях сохранить все созданные объекты когда вызывается Save(). Вот классы. Я не знаю, как сделать сопоставление отношения один ко многим между Parent и Child, что облегчит сохранение всех созданных объектов за один звонок до Save(). Я ожидаю, что можно использовать любую версию, но только один будет использоваться в любой момент времени. Обоснование этого заключается в том, что я создаю сборщики тестовых данных, и в некоторых случаях будет проще подключить его со стороны Child, а в других случаях будет легче подключаться к стороне Parent. Поэтому я хочу иметь возможность каскадировать вставки и удаления в обоих направлениях, заданных любым объектом. Меня не интересуют обновления. Это будет использоваться только для вставки данных, выполнения моих тестов против приложения, а затем удаления данных.

Вот классы, участвующие:

public class Child { 
    public virtual int Id { get; set; } 
    public virtual string Name { get; set; } 
    public virtual Parent Parent { get; set; } 
} 

public class Parent { 
    public virtual int Id { get; set; } 
    public virtual string Name { get; set; } 
    public virtual IEnumerable<Child> Children { get; set; } 
} 

public ChildMap : ClassMap<Child> { 
    public ChildMap() { 
    Id(x => x.Id); 
    Map(x => x.Name); 

    // How should I set this up? 
    Reference(x => x.Parent); 
    } 
} 

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

    // How should I set this up ? 
    HasMany(x => x.Children); 
    } 
} 
+0

это лучше сделать сбор детей только для чтения и использовать синтаксис инициализации: 'новые Родительские {Дети = { new Child {Name = "bar"}, new Child {Name = "baz"}, }}; '. – Firo

+0

@ Фиро вы могли бы превратить это в полный ответ? –

+0

Лучше всего это делать (особенно с ORM), но это не отвечает на вопрос. ИМО Радим Кёлер дал хороший и полный ответ. – Firo

ответ

2

Чтобы иметь возможность сохранить каскады с обеих сторон, мы можем просто использовать настройки

Так каскад, это отображение будет достаточно:

public ChildMap() 
{ 
    ... 
    BatchSize(100); // this is the way how to solve 1 + N (good practice, mine at least) 

    // How should I set this up? 
    References(x => x.Parent) // References, not Reference 
     .Cascade.SaveUpdate() 
     ; 
} 

public ParentMap() 
{ 
    ... 
    BatchSize(100); // this is the way how to solve 1 + N 

    // How should I set this up ? 
    HasMany(x => x.Children) 
     .BatchSize(100) // no 1 + N 
     .Cascade.AllDeleteOrphan() 
     .Inverse() 
     ; 

С этими настройками вышеописанное будет работать с одним важным изменением - дети ДОЛЖНЫ знать о своем родителе. Поскольку мы используем обратный ...

Это будет работать:

var child = new Child 
{ 
    Name = "foo", 
    Parent = new Parent {Name = "bar"} 
}; 

session.Save(child); 
session.Flush(); 
session.Clear(); 

var persistedChild = session.Get<Child>(child.ID); 

И это будет так же (но с установкой child.Parent ссылка)

var parent = new Parent 
{ 
    Name = "foo", 
    Children = new List<Child> 
    { 
     new Child {Name = "bar"}, 
     new Child {Name = "baz"}, 
    }, 
}; 

foreach (var ch in parent.Children) 
{ 
    ch.Parent = parent; // we MUST do this, there is .Inverse() 
} 

session.Save(parent); 
session.Flush(); 
session.Clear(); 

var persistedParent = session.Get<Parent>(parent.ID); 

Read more here о batch size (не часть вопроса, но я использую ее всегда)

Дополнительная информация об обратном картографировании и reference assignment

А также, почему мы не можем использовать один и тот же каскад на .Rferences() (много-к-одному) NHibernate Many-to-one cascade

Смежные вопросы