Searching a tree using LINQ
It's a misconception that this requires recursion. It will require a stack or a queue and the easiest way is to implement it using recursion. For sake of completeness I'll provide a non-recursive answer.
static IEnumerable<Node> Descendants(this Node root)
{
var nodes = new Stack<Node>(new[] {root});
while (nodes.Any())
{
Node node = nodes.Pop();
yield return node;
foreach (var n in node.Children) nodes.Push(n);
}
}
Use this expression for example to use it:
root.Descendants().Where(node => node.Key == SomeSpecialKey)
Linq recursive search nodes
Another linq recursive solution:
public static IEnumerable<Node> GetAllNodes( Node root )
{
if( root == null )
{
yield break;
}
yield return root;
if ( root.Nodes == null )
{
yield break;
}
foreach ( Node descendant in root.Nodes.SelectMany( GetAllNodes ) )
{
yield return descendant;
}
}
Use like this:
Items.SelectMany( GetAllNodes )
Retrieving a tree structure from a database using LINQ
I'd add a field to the entity to include the parent ID, then I'd pull the whole table into memory leaving the List subs null. Id then iterate through the objects and populate the list using linq to objects. Only one DB query so should be reasonable.
Query a binary tree
The problem you seem to have is that you criteria is impossible.
Take this line: MC.Where(x => ((ID)x).DealNo == 2 && ((ID)x).Strategy == "Fly" && ((Greek)x).GreekType == "Delta" && ((DataPoint)x).DpNo == 14)
. It is kind of saying that you expect each member of MC
to be of type ID
, Greek
, and DataPoint
all at the same time.
Based on your comments it sounds like you need this:
var query =
from id in MC.OfType<ID>()
from greek in id.Children.OfType<Greek>()
from dp in greek.Children.OfType<DataPoint>()
group dp.Value by new
{
id.DealNo,
id.Strategy,
greek.LegOrPos,
greek.GreekType,
dp.DpNo
} into gs
select new
{
gs.Key,
Value = gs.Sum(),
};
When I run that on your data I get this:
How to search Hierarchical Data with Linq
That's an extension to It'sNotALie.
s answer.
public static class Linq
{
public static IEnumerable<T> Flatten<T>(this T source, Func<T, IEnumerable<T>> selector)
{
return selector(source).SelectMany(c => Flatten(c, selector))
.Concat(new[] { source });
}
}
Sample test usage:
var result = familyRoot.Flatten(x => x.Children).FirstOrDefault(x => x.Name == "FamilyD");
Returns familyD
object.
You can make it work on IEnumerable<T>
source too:
public static IEnumerable<T> Flatten<T>(this IEnumerable<T> source, Func<T, IEnumerable<T>> selector)
{
return source.SelectMany(x => Flatten(x, selector))
.Concat(source);
}
Related Topics
How to Compare Two Rich Text Box Contents and Highlight the Characters That Are Changed
Differencebetween Declarative and Imperative Paradigm in Programming
How to Inject a Dbcontext Instance into an Ihostedservice
Performance Difference for Control Structures 'For' and 'Foreach' in C#
Enabling C# 7 in a ASP.NET Application
How to Pass Parameters to Another Process in C#
How to Automatically Scroll to the Bottom of a Multiline Text Box
How to Detect a Usb Drive Has Been Plugged In
Get Return Value from Stored Procedure
Not Ableto Serialize Dictionary with Complex Key Using JSON.Net
String = String + Int: What's Behind the Scenes
Simple State MAChine Example in C#
How to Do Template Specialization in C#
How to Justify Text in a Label
How to Reference Generic Classes and Methods in Xml Documentation