Eric Greenberg
Eric Greenberg

Reputation: 13

How do I use LINQ to access a specific value from of an array of JObjects that seems to be stored in a string

I'm making a database call in C# that looks something like this:

public JArray GetEmployeeInfo(string search_text)
{
    var search = search_text.Split(' ');

    var dataObject = _db.Employee
        .Where(x => x.Usage.Equals("basic") &&
                    search.All(s => x.EmployeeName.Contains(s) || 
                                    x.EmployeeEmailAddress.Contains(s) || 
                                    x.EmployeeId.Contains(s)))
        .Select(x => new
        {
            x.EmployeeId,
            x.EmployeeName,
            x.EmployeeEmailAddress,
            x.EmployeeDepartmentName,
            x.UsageTags
        });

    return JArray.FromObject(dataObject);
}

Which works fine. The issue is the format of the data that's being returned. It looks something like this:

{
  "EmployeeId": "000012345",
  "EmployeeName": "Firstname Lastname",
  "EmployeeEmailAddress": "[email protected]",
  "EmployeeDepartmentName": "Accounting",
  "EmployeeType": "Staff",
  "UsageTags": "[{\"seqNo\":1,\"Tag\":\"CurrentEmpl:Accountant\"},{\"seqNo\":2,\"Tag\":\"CurrentEmpl:Manager\"},{\"seqNo\":3,\"Tag\":\"Intern:Attended\"}]"
}

and what I need is to have UsageTags be an array of the Tag values, like this:

{
  "EmployeeId": "000012345",
  "EmployeeName": "Firstname Lastname",
  "EmployeeEmailAddress": "[email protected]",
  "EmployeeDepartmentName": "Accounting",
  "EmployeeType": "Staff",
  "UsageTags": ["CurrentEmpl:Accountant", "CurrentEmpl:Manager", "Intern:Attended"]
}

Right now, I'm formatting it in JavaScript, but it would be a lot better if I could just write out a LINQ statement that does it on the server side. I wasted most of today trying different solutions from here, along with Google and my old C# Cookbook, but nothing seems to do the trick.

Anyone have a solution that would somehow parse the UsageTags into an array of JObjects, then pull out the values of all the Tag keys and toss the values in an array? Because, I am going crazy banging my head against this one.

Upvotes: 1

Views: 128

Answers (1)

Brian Rogers
Brian Rogers

Reputation: 129777

It looks like UsageTags is a string already containing JSON, so you'll need to deserialize it in each item so that you can extract the tag names.

Try something like this:

public JArray GetEmployeeInfo(string search_text)
{
    var search = search_text.Split(' ');

    var dataObject = _db.Employee
        .Where(x => x.Usage.Equals("basic") && 
                    search.All(s => x.EmployeeName.Contains(s) || 
                                    x.EmployeeEmailAddress.Contains(s) || 
                                    x.EmployeeId.Contains(s)))
        .Select(x => new
        {
            x.EmployeeId,
            x.EmployeeName,
            x.EmployeeEmailAddress,
            x.EmployeeDepartmentName,
            x.UsageTags
        })
        .ToList();    // materialize the database query

    var array = new JArray(
        dataObject.Select(o =>
        {
            var jo = JObject.FromObject(o);
            // parse and transform the UsageTags
            jo["UsageTags"] = new JArray(
                JArray.Parse((string)jo["UsageTags"])
                      .Select(jt => jt["Tag"])
            );
            return jo;
        })
    );

    return array;
}

Working demo here: https://dotnetfiddle.net/nbHbkZ

Upvotes: 1

Related Questions