2

我收到了经典错误:

'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();
    }

我没有将它们添加为父节点的新权利,只是相关的补充。

4

1 回答 1

1

只是为了完整性。消息“已删除的对象将被重新保存..”是由显式调用引起的session.Delete(instance)

在这种情况下,我们只需要 1) 从旧的父集合中删除此类项目,然后 2) 将其附加到新的父集合。级联映射和 session.Flush() 将正确更新数据库。

最后说明:这样的“移动”必须在一个会话/事务中完成,以避免其他问题(例如,“行已被另一事务更新或删除......”)。

于 2014-01-20T17:39:19.267 回答