Reputation: 167
I have used the following linq query to access the member Names. The following successfully returns all member Name values within the collection.
var we = CsQ.Groups.SelectMany(g => g.Members).Where(a => a.Name == "Name").Select(b => b.Value).ToList();
I want to now filter this down based another property within "Members" called AbsoluteUri which is nested in a property AgentsByUri. This doesnt work but gives an idea of the structure:
var uri = CsQ.Groups.SelectMany(g => g.Members).Where(a => a.Name == "AgentsByUri").Select(b => b.Value).//??? I NEED TO NOW ACCESS "AbsoluteUri"
How can I combine these in to one query so that I can return only the "Names" that have an "AbsoluteUri" that contains "SomeValue". AbsoluteUri seems to be nested in a collection thats nested in AgentsByUri which adds to the complication.
You can see the structure of the AgentsByUri object here - Using C# Linq to query nested objects
Excuse my terminology, I'm reasonably new to C#! Hopefully this makes sense :)
Any help or guidance VERY appreciate :)
EDIT3 Getting somewhere! Casting as dynamic partially working - member.AgentsByUri is now OK, just cant figure out how to make it apply to the rest of the query. Tried adding in various locations by no luck.
EDIT2 Thanks for everyone's input. I haven't had any further success. I think the biggest problem is that I am dealing with a PowerShell object which is dynamically generated at run time. As a result I cannot access the classes/object because the compiler doesn't yet no about them. To get around this I use the "dynamic" type which allows the compiler to trust that what I provide will be valid at run time. Can I cast as dynamic in a linq query? Or do I need to go about this in a different way?
Heres what I get with the examples give:
EDIT1 (click and zoom, image is high res):
Upvotes: 0
Views: 1910
Reputation: 495
I'm just writing this down, based on the image you provided. However, I can not check for correctness without the surrounding code, so no guarantees.
var uri = CsQ.Groups
.SelectMany(g => g.Members)
.Where(m => m.AgentsByUri.SelectMany(a => a.Value, (a, v) => v.AbsoluteUri).Contains("SomeValue"))
.Select(b => b.Value)
In LINQ syntax it should be much clearer
var uri =
from group in CsQ.Groups
from dynamic member in group.Members
where
(from agent in (IEnumerable<dynamic>)member.AgentsByUri
where agent.Name = "AgentsByUri" // this line may be redundant
from x in (IEnumerable<dynamic>)agent.Value
select x.AbsoluteUri).Contains("SomeValue")
select member.Value;
EDIT: The suggestion in my second comment does not quite work. I changed the code in LINQ syntax above to account for dynamic objects as the source by explicitly casting to IEnumerable<dynamic>
. Note however that the cast will fail for an enumeration of a value type.
I hope this will work for you.
Upvotes: 1
Reputation: 407
I had to do some digging and make a few assumptions here:
var we = CsQ.Groups.SelectMany(g => g.Members).Where(member => member.Name == "AgentsByUri" && member.Value != null && member.Value.Any(uri => uri.AbsoluteUri == "SomeValue")).ToList();
Upvotes: 1
Reputation: 4440
It's hard to give a proper answer without having a proper overview of the class structure. I guess this might work:
var uri = CsQ.Groups.SelectMany(g => g.Members).Where(a => a.Name == "AgentsByUri").Select(b => b.Value).Where(x => x.AbsoluteUri == "SomeValue");
Upvotes: 1