我收到了经典错误:
'deleted object would be re-saved by cascade
(remove deleted object from associations)[DrillingContracts.Domain.TrackedField#3216'
但是有一个额外的转折,错误的起源完全是因为我正在删除一个实体并添加一个新实体。
我用这种方法清空所有已存在的孩子
public void RemoveChildren(TrackedNode parentNode)
{
foreach (TrackedField trackedField in parentNode.ChildNodes)
{
_trackedFieldRepository.Delete(trackedField);
parentNode.RemoveChildNode(trackedField);
}
}
然后立即添加新的
public virtual void AddTrackedChildFieldsToTrackedCell(
params TrackedField[] nodes)
{
foreach (var field in nodes)
{
if (IsPath(field.Name))
{
throw new InvalidTrackedFieldNameException(
"The value " + field.Name + " is not a valid tracked field name.");
}
field.Supplement = this;
_trackedFields.Add(field);
}
}
对于那些想知道存储库中发生了什么的人,我得到的最佳答案就是魔术。 10,000%魔法。最初的开发人员使用NCommon。这两个方法都是从NCommon.UnitOfWork属性中包含的方法调用的。
应该注意,每种方法都按预期执行。 (IE,没有字段可以删除添加作品,同样,没有字段可以添加删除作品。)
修改
[HttpPost]
[UnitOfWork(Scope = FilterScope.Result)]
public ActionResult SaveEditMode(long id, AddTrackedRowViewModel model, string editMode, List<string> elementNames, string provisionData)
{
var supplement = _supplementCoordinator.GetSupplement(id);
var table = supplement.TrackedTables.First(x => x.Name == model.Name);
var valueAttributes = JsonSerializer.DeserializeFromString<List<ValueAttributeViewModel>>(provisionData);
foreach (var prop in valueAttributes)
{
supplement.Set(prop.Attribute, prop.Value, false);
}
var cell = table.TrackedRows.First(x => x.Ordinal == model.Ordinal).TrackedCells.First(x => x.Name == "Detail");
_supplementCoordinator.RemoveChildren(cell);
if (elementNames != null)
{
var childNodes = elementNames.Select((t, i) => new TrackedField(cell, t, i)).ToList();
supplement.AddTrackedChildFieldsToTrackedCell(childNodes.ToArray());
}
return SwitchEditMode(model, editMode, table);
}
答案
public void AddChildren(Supplement supplement, TrackedNode parentNode, params TrackedField[] nodes)
{
foreach (TrackedField trackedField in nodes)
{
parentNode.AddChildNode(trackedField);
}
supplement.AddTrackedChildFieldsToTrackedCell();
}
我没有将它们添加为父节点的新权限,只是相关的补充。
答案 0 :(得分:1)
只是为了完整。消息'已删除的对象将被重新保存..'是由显式调用session.Delete(instance)
引起的。
在这种情况下,我们只需要1)从旧的父集合中删除这样的项目,然后2)将它附加到新的父项。级联映射和session.Flush()将正确地更新DB。
最后注意事项:这样的“移动”必须在一个会话/事务中完成,以避免其他问题(例如'Row被另一个事务更新或删除......')。