Umbraco 7:如何在Descendants Where()子句中排除多节点树选择器选中的节点
Got it, let's sort this out for you! The key here is to compare the IDs of the nodes you want to exclude against the descendants you're fetching—this is the most reliable way since node IDs are unique and avoids any potential issues with object reference comparisons.
Here's how you can implement the Where() filter properly:
Basic Implementation
First, extract the IDs of the nodes you've picked with the multinode treepicker, then exclude any descendant nodes that match those IDs:
var exclude_nodes = CurrentPage.pickedNodes; // Grab the IDs of the nodes we want to exclude var excludeIds = exclude_nodes.Select(n => n.Id); // Fetch descendants and filter out excluded nodes var nodes = Model.Content.AncestorsOrSelf("homepage") .First() .Descendants("addonProduct") .Where(node => !excludeIds.Contains(node.Id));
Handle Empty Exclusion List
If there's a chance the treepicker might be empty (no nodes selected), add a null check to avoid NullReferenceException:
// Default to an empty collection if no nodes are picked var exclude_nodes = CurrentPage.pickedNodes ?? Enumerable.Empty<IPublishedContent>(); var excludeIds = exclude_nodes.Select(n => n.Id); var nodes = Model.Content.AncestorsOrSelf("homepage") .First() .Descendants("addonProduct") .Where(node => !excludeIds.Contains(node.Id));
Additional Safeguards
If you're working with an older Umbraco version where pickedNodes returns dynamic instead of IPublishedContent, cast it explicitly:
var exclude_nodes = CurrentPage.pickedNodes.Cast<IPublishedContent>() ?? Enumerable.Empty<IPublishedContent>(); var excludeIds = exclude_nodes.Select(n => n.Id);
Also, to avoid crashes if no "homepage" ancestor is found, replace First() with FirstOrDefault() and add a null check:
var homepage = Model.Content.AncestorsOrSelf("homepage").FirstOrDefault(); if (homepage != null) { var exclude_nodes = CurrentPage.pickedNodes ?? Enumerable.Empty<IPublishedContent>(); var excludeIds = exclude_nodes.Select(n => n.Id); var nodes = homepage.Descendants("addonProduct") .Where(node => !excludeIds.Contains(node.Id)); // Work with your filtered nodes here }
Alternative: Compare Node Objects (Less Recommended)
You could also compare the node objects directly, but this is less reliable than using IDs (since in some cases, object references might differ even for the same node):
var exclude_nodes = CurrentPage.pickedNodes; var nodes = Model.Content.AncestorsOrSelf("homepage") .First() .Descendants("addonProduct") .Where(node => !exclude_nodes.Contains(node));
Sticking with the ID-based approach is always the safer bet here!
内容的提问来源于stack exchange,提问作者sjodough

