Цитата
Мы используем метод ByCode для сопоставления наших данных.
У меня есть объект Process (таблица процессов), который имеет список объектов ProcessStep (таблица ProcessStep), который, в свою очередь, имеет объекты Bag of ProcessStepUser (таблица ProcessStepUser), назначенные каждому шагу.
Объекты загружаются просто отлично, но на веб-странице, если я удаляю шаг из коллекции, регидратирую в действие MVC как процесс, а затем сохраняю процесс, шаг в базе данных просто имеет значение ProcessId, установленное на ноль, что разрывает ссылку, но оставляет шаг в базе данных и всех назначенных ему пользователей.
Что я хочу сделать, так это удалить шаг и удалить его ProcessStep и всех его ProcessStepUsers.
Точно так же, когда я редактирую ProcessStep (скажем, я меняю имя шага) и сохраняю, он сохраняет это, но пользователи ProcessStep обнуляются (их ProcessStepId) и создаются заново, оставляя потерянные записи.
У меня также есть столбец ProcessStepUser для общего ProcessId, так что я могу предотвратить назначение пользователя более одного раза на любой шаг процесса.
Мое соответствующее сопоставление выглядит следующим образом:
Процесс:
List(x => x.ProcessSteps, m =>
{
m.Key(k => k.Column("ProcessId"));
m.Index(i => i.Column("StepOrder"));
m.Lazy(CollectionLazy.NoLazy);
m.Cascade(Cascade.All);
m.Inverse(false);
},
r => r.OneToMany(o => o.Class(typeof (ProcessStep))));
Шаг процесса:
Bag(x => x.ProcessStepUsers, m =>
{
m.Key(k => k.Column("ProcessStepId"));
m.Lazy(CollectionLazy.NoLazy);
m.Cascade(Cascade.All);
m.Inverse(false);
},
r => r.OneToMany(o => o.Class(typeof (ProcessStepUser))));
ManyToOne(x => x.Process, m =>
{
m.Column("ProcessId");
m.Class(typeof (Process));
});
ПроцессШепПользователь
ManyToOne(p => p.Step, m =>
{
m.Column("ProcessStepId");
m.Class(typeof (ProcessStep));
});
ManyToOne(p => p.Process, m =>
{
m.Column("ProcessId");
m.Class(typeof (Process));
});
Как я уже сказал, он отлично сохраняется при создании и отлично загружается для отображения. Но удаление шага или редактирование шага создает хаос в базе данных.
Я взломал процесс удаления шагов, пометив их и удалив вручную перед сохранением главного объекта процесса, но я бы хотел, чтобы nhibernate делал все это, если это возможно.
Спасибо!
Цитата
Во-первых, спасибо Мартину, который обнаружил одну проблему с Cascade.All.Include(Cascade.DeleteOrphans)... это был исходный код, который у меня был, я забыл, что изменил его, пытаясь решить проблему.
Я переписал некоторые тесты, и сопоставление на самом деле работает просто отлично, так что приношу свои извинения. Я бы удалил этот вопрос, но сайт не позволяет мне ничего (в Firefox), кроме редактирования...
Проблема оказалась в том, что я получал объект Process из базы данных, а затем сериализовал его в View как объект JSON. Затем я вернул объект JSON, который был привязан к объекту Process.
Короче говоря, наш репозиторий вызывал SaveOrUpdate(obj) для объекта, но, поскольку он был отключен, нам нужно было вызвать Merge(obj), что мы и сделали, и все работало отлично.
Я оставляю власть предержащим решать, имеет ли этот вопрос какую-либо ценность.
Спасибо!