DbContext未标记实体已修改 - 将MonitorTag添加到节点

时间:2016-08-05 16:40:40

标签: c# entity-framework entity-framework-6 dbcontext

我试图理解为什么我的逻辑在将MonitorTag添加到MonitorTag导航属性时没有将实体(NWatchNode)标记为已修改。

以下是代码,我将在下面简要解释:

using (NWatchDbContext context = Application.GetDbContext()) {

    var rootAndChildNodes =
        GetRootAndChildNodesIncludeTags(rootNode, context);
    var uniqueTags = GetUniqueTags(allTags, context);

    var ports = FlattenModelExtendedInfo(routerInfo);

    PerformMonitorTagOperationInternal(tagOper, rootAndChildNodes, uniqueTags, ports);

    // Mark tags as unchanged, otherwise DbContext will
    // create a duplicate.
    MarkTagsUnchanged(context);

    context.SaveChanges();
}

步骤摘要:

  1. 获取根节点和子节点,包括他们的MonitorTag。
  2. 获取唯一标记(通过查看所有传入的标记以及已由DB Context检索的标记。
  3. 获取端口类型(对此问题不重要)
  4. 将适当的标签应用于根节点和子节点(如果它们尚未应用它们)
  5. 标记标记不变(阻止DbContext考虑分离的标记" new",因为我已经知道它们存在于数据库中。
  6. 保存更改。
  7. 现在,我正在努力解决这个问题: 如果我在MarkTagsUnchanged(context)行上放置断点,则rootAndChildNodes [0](根节点)已将MonitorTag添加到它的MonitorTag集合中。

    但是,在即时窗口中运行context.Entry(rootAndChildNodes[0]).State会返回Unchanged,但我知道在步骤4(PerformMonitorTagOperationInternal(tagOper, rootAndChildNodes, uniqueTags, ports);)添加了MonitorTag

    为什么rootAndChildNodes[0]不被视为已修改,即使已将MonitorTag添加到其MonitorTags集合中?

    以下是refence的PerformMonitorTagOperationInternal()方法:

    private void PerformMonitorTagOperationInternal(TagOperation operation,
        INWatchNodeEntity[] rootAndChildren,
        NWatchMonitorTag[] monTags,
        Dictionary<long, CasApiPortType> ports)
    {
        foreach (var node in rootAndChildren) {
            // Check to see if node is Router
            if ((node.NodeType & NetworkDeviceNodeType) > 0) {
                var tag = monTags.
                    FirstOrDefault(x => x.Name.Equals(Prefix + NetworkDevicePrefix + node.NodeType,
                    StringComparison.CurrentCultureIgnoreCase));
    
                if (tag != null) {
                    PerformTagOperation((NWatchNode)node, tag, operation);
                }
            } else if (node.NodeType == NWatchNodeType.Other) {
                // This would occur if Spectrum has the device as an "SNMP" model class
                var tag = monTags.
                    FirstOrDefault(x => x.Name.Equals(Prefix + NetworkDevicePrefix + NWatchNodeType.NetworkL3Switch,
                    StringComparison.CurrentCultureIgnoreCase));
    
                if (tag != null) {
                    PerformTagOperation((NWatchNode)node, tag, operation);
                }
            } else if (node.NodeType == NWatchNodeType.NetworkInterface
             && ports.Keys.Contains(node.NativeId)) {
    
                CasApiPortType portType = ports[node.NativeId];
                if (PortMonitoringTagNamesDictionary.Keys.Contains(portType)) {
                    string[] tagNames = PortMonitoringTagNamesDictionary[portType];
    
                    var tags = monTags.
                        Where(x => tagNames.Contains(x.Name)).ToArray();
    
                    foreach (var tag in tags) {
                        PerformTagOperation((NWatchNode)node, tag, operation);
                    }
                }
            }
        }
    }
    

    以下是PerformTagOperation方法供参考:

    private void PerformTagOperation(NWatchNode node, NWatchMonitorTag tag, TagOperation operation)
    {
        switch (operation) {
            case TagOperation.AddTag:
                Trace.TraceInformation("Applying tag {0} to {1}.", tag.Name, node.Name);
    
                if (tag != null && !node.MonitorTags.Contains(tag)) {
                    node.MonitorTags.Add(tag);
                    Trace.TraceInformation("Applied tag {0} to {1}.", tag.Name, node.Name);
                    // Run OnDiscovery for NetworkInterface node time
                    if (node.NodeType == NWatchNodeType.NetworkInterface) {
                        Application.Query(new INWatchNode[] { node }, NetworkInterfaceOnDiscoverQuery.AllAttributes);
                    } else if (node.NodeType == NWatchNodeType.NetworkRouter || 
                        node.NodeType == NWatchNodeType.NetworkL3Switch ||
                        // Below accounts for Router being defined as SNMP Model Class
                        node.NodeType == NWatchNodeType.Other) {
                        Application.Query(new INWatchNode[] { node }, NetworkRouterOnDiscoverQuery.AllAttributes);
                    }
                } else {
                    Trace.TraceInformation("Tag {0} is already associated to {1}.", tag.Name, node.Name);
                }
                break;
            case TagOperation.RemoveTag:
                Trace.TraceInformation("Removing tag {0} from {1}.", tag.Name, node.Name);
                if (node.MonitorTags.Contains(tag)) {
                    node.MonitorTags.Remove(tag);
                    Trace.TraceInformation("Removed tag {0} from {1}.", tag.Name, node.Name);
                } else {
                    Trace.TraceInformation("Tag {0} was not associated with {1}.", tag.Name, node.Name);
                }
                break;
        }
    }
    

0 个答案:

没有答案