0

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.

Cast as dynamic

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:

Compiler error when trying to access dynamic object

EDIT1 (click and zoom, image is high res): Data Structures

6
  • 1
    Can you please clarify the classes structures? the pictures on the linked answer are small and blurry Commented Sep 10, 2015 at 21:01
  • Linq doesn't do recursion. Create a recursive function and put the Linq inside the recusive function. Commented Sep 10, 2015 at 21:18
  • 1
    Just include the classes in your question. As code, not as images. Nobody likes to give answers based on incomplete information. Commented Sep 10, 2015 at 21:41
  • Thanks all for the comments, really appreciate it. A few of you wanted some clarity around the data I am working with. I have updated the post with an image that should show you this. Commented Sep 10, 2015 at 23:24
  • Sorry, this really doesn't work. Why don't you capture the dynamic type in a structure of named types, if only for the sake of showing it here? Commented Sep 11, 2015 at 7:15

3 Answers 3

1

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.

Sign up to request clarification or add additional context in comments.

4 Comments

Try .Cast<dynamic>()
Getting somewhere with this! See EDIT3
This looks interesting, I just don't quite follow it :) - c-sharpcorner.com/UploadFile/FreeBookArticles/AddisonWesley/…
You would have to apply it to every dynamic object, presumably member, agent and x. Btw. explicitly specifying the type as dynamic. e.g. from dynamic member in g.Membersis equivalent to from member in g.Members.Cast<dynamic>()
1

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");

Comments

1

I had to do some digging and make a few assumptions here:

  1. You want to return a list of PSMemberInfo.
  2. PsMemberInfo.Name must equal "AgentsByUri".
  3. In the Value property (which is a collection of Uri), you want to filter this collection on items whose AbsoluteUri property equals "SomeValue".
var we = CsQ.Groups.SelectMany(g => g.Members).Where(member => member.Name == "AgentsByUri" && member.Value != null && member.Value.Any(uri => uri.AbsoluteUri == "SomeValue")).ToList();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.