Search code examples
c#.netlinqlinq-to-entities

Linq Search by Dictionary value


I am trying to search contacts (Objects) that contains a List<Dictionary<string, string>> by a dictionary key and value

Below is my Json Array of Contacts

[
  {
    "first_name": "David",
    "last_name": "Smith",
    "email": "[email protected]",
    "phone": "1234567890",
    "website": "google.com",
    "relations": [
      {
        "listid": "65512fe1e759b98f40b48829"
      },
      {
        "listid": "34212fe1e759b98f40b48829"
      }
    ]
  },
  {
    "first_name": "Chris",
    "last_name": "Oven",
    "email": "[email protected]",
    "phone": "1234567890",
    "website": "google.com",
    "relations": [
      {
        "listid": "65512fe1e759b98f40b48829"
      },
      {
        "listid": "34212fe1e759b98f40b48829"
      }
    ]
  }
]

I am trying to find all contacts that contain listid = "65512fe1e759b98f40b48829".

What is the best way to do this using Linq?

Tried something like below:

var searchPair = new KeyValuePair<string, string>("listid", "65512fe1e759b98f40b48829");

contacts.Where(p=>p.relations.Where(dictionary => dictionary[searchPair.Key].ToString().Contains(searchPair.Value)).ToList();

but somewhere it is giving incorrect way for searching


Solution

  • It seems to me that this is a better representation of your JSON:

    public class Customer
    {
        [JsonProperty("first_name")]
        public string FirstName { get; set; }
    
        [JsonProperty("last_name")]
        public string LastName { get; set; }
    
        [JsonProperty("email")]
        public string Email { get; set; }
    
        [JsonProperty("phone")]
        public string Phone { get; set; }
    
        [JsonProperty("website")]
        public string Website { get; set; }
    
        [JsonProperty("relations")]
        public List<Relation> Relations { get; set; }
    }
    
    public class Relation
    {
        [JsonProperty("listid")]
        public string ListId { get; set; }
    }
    

    Now you can read in your data:

    List<Customer> customers =
        Newtonsoft
            .Json
            .JsonConvert
            .DeserializeObject<List<Customer>>(
                File.ReadAllText(@"customers.json"));
    

    That gives:

    Deserialized JSON

    Now querying it is simple:

    IEnumerable<Customer> query =
        from c in customers
        where c.Relations.Any(r => r.ListId == "65512fe1e759b98f40b48829")
        select c;
    

    Here's the query if you use the dictionary version of relations you suggested:

    IEnumerable<Customer> query =
        from c in customers
        where c.Relations.Any(r => r.TryGetValue("listid", out string value)
            && value == "65512fe1e759b98f40b48829")
        select c;