我试图理解为什么我的逻辑在将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();
}
步骤摘要:
现在,我正在努力解决这个问题:
如果我在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;
}
}