Linda Lawton - DaImTo
Linda Lawton - DaImTo

Reputation: 116918

Find object with in class using LINQ

I want to return the item that has the profile ID I send. So in order to do this I will need to loop through all of the Items -> WebProproperties -> profile. The Class structure is at the end of the question.

I would rather use LINQ than create a nested foreach. I have been trying to get this to work for more than an hour now. I am stuck.

My first idea was to simply use where. But that doesn't work because you need to have something on the other side that needs to equal.

this.Accounts.items.Where(a => a.webProperties.Where(b => b.profiles.Where(c => c.id == pSearchString)) ).FirstOrDefault();

My second idea was to try using Exists which I don't have much experience with:

Item test =  from item in this.Accounts.items.Exists(a => a.webProperties.Exists(b => b.profiles.Exists(c => c.id == pSearchString))) select item;

This doesn't work either:

Could not find an implementation of query pattern for source type 'Bool'

    public RootObject Accounts {get; set;}

    public class RootObject
    {
        public string kind { get; set; }
        public string username { get; set; }
        public int totalResults { get; set; }
        public int startIndex { get; set; }
        public int itemsPerPage { get; set; }
        public List<Item> items { get; set; }
    }

    public class Profile
    {
        public string kind { get; set; }
        public string id { get; set; }
        public string name { get; set; }
        public string type { get; set; }
    }

    public class WebProperty
    {
        public string kind { get; set; }
        public string id { get; set; }
        public string name { get; set; }
        public string internalWebPropertyId { get; set; }
        public string level { get; set; }
        public string websiteUrl { get; set; }
        public List<Profile> profiles { get; set; }
    }

    public class Item
    {
        public string id { get; set; }
        public string kind { get; set; }
        public string name { get; set; }
        public List<WebProperty> webProperties { get; set; }
    }

Upvotes: 4

Views: 2304

Answers (3)

Dhaval Patel
Dhaval Patel

Reputation: 7601

You can use the below mentioned code.

var abc = rr.items.Where(p => p.webProperties.Any(c => c.profiles.Any(d => d.id == "1"))).FirstOrDefault();

Just for your reference, your class should look like:

public class RootObject
{
    public string kind { get; set; }
    public string username { get; set; }
    public int totalResults { get; set; }
    public int startIndex { get; set; }
    public int itemsPerPage { get; set; }
    private List<Item> _items=new List<Item>();

    public List<Item> items
    {
        get { return _items; }
        set { _items = value; }
    }
}

Upvotes: 0

StuartLC
StuartLC

Reputation: 107247

You can use Any() to determine existence. Also, note that many of the extension methods have overloads which take a predicate, including FirstOrDefault():

this.Accounts.items.FirstOrDefault(a => a.webProperties
      .Any(b => b.profiles
          .Any(c => c.id == pSearchString)));

Upvotes: 6

Mashton
Mashton

Reputation: 6415

You are looking for the .Any() operation I think. This will return true/false for whether there are any items matching your query.

For example:

if (this.Accounts.Items.Any(i=>i.webProperties.Any(wp=>wp.profiles.Any(p=>p.id == MySearchId)));

EDIT: You have full answer (was posted while I was composing mine) and as pointed out in comments my answer isn't actually returning your found item, just letting you know whether there is one. You can rework the first .Any to be a .FirstOrDefault to get that match. E.g.

var result = this.Accounts.Items.FirstOrDefault(i=>i.webProperties.Any(wp=>wp.profiles.Any(p=>p.id == MySearchId)))

Upvotes: 1

Related Questions