0

I have a datatable like below which contains several columns. One of the datatable column has value as json array ( Contacts ). I want to access name property from the column.

Name     ID    Contacts 
User1    1     [{ "id": 1, "name": "User3", } }]]
10
  • 2
    Database columns don't contain arrays. Most likely you mean that Contacts contains a JSON string. Use JSON.NET or another JSON serializer to read the contents. Commented Oct 15, 2018 at 7:25
  • Which database are you using? SQL Server 2016+ and PostgreSQL have JSON funcions which means you could just extract the contact names instead of the entire object. Otherwise you'll have to deserialize the JSON string and read the name value Commented Oct 15, 2018 at 7:26
  • Its a datatable with json(converted to string). Commented Oct 15, 2018 at 7:44
  • @PanagiotisKanavos its not true. Postgresql has arrays but only simple one dimensional. Commented Oct 15, 2018 at 7:48
  • @daremachine what isn't true? That Postgres supports JSON? That this data looks like JSON? Do we really need to start a discussion about SQL, the language vs the customizations introduced by each vendor and how easy or hard it is to index and query multivalue fields even when they are available? Thus making multivalue columns problematic even when they are available? Commented Oct 15, 2018 at 7:52

1 Answer 1

1

This table contains a JSON string, not an array. To get the field's contents one would have to deserialize it using JSON.NET and read its contents, eg :

var contactValue=(string)table.Rows[0]["Contacts"];            
var contacts=JsonConvert.DeserializeObject<dynamic>(contactValue);
Console.WriteLine("{0}",contacts[0].name);

JsonConvert.DeserializeObject can deserialize a JSON string into a concrete type or a dynamic object. In this example the contents are deserialized into a dynamic object that contains an array. contacts[0].name will return the name attribute of the first element.

It's better to create a concrete type instead of using dynamic in this case:

class Contact 
{
        public int id {get;set;}
        public string name{get;set;}
}

This allows the use of LINQ to retrieve specific attributes, eg :

var  contacts=JsonConvert.DeserializeObject<Contact[]>(contactValue);

//Iterate over the results
foreach(var contact in contacts)
{
    Console.WriteLine(contact.name);
}
//Or use LINQ
var names=contacts.Select(it=>it.name).ToList();

Using JSONPath

Another option could be to use JSONPath to extract specific values without parsing the entire string.

Instead of deserializing the string, it's parsed with JArray.Parse or JObject.Parse. After that, SelectTokens is used to retrieve the values that match a query path:

var array=JArray.Parse(contactValue);
var tokens=array.SelectTokens("$..name");
foreach(var token in tokens)
{
    Console.WriteLine(token);
}
//Concatenate all names into a string
string allNames=String.Join(",",tokens);

$..name means

For any element, return any attribute named name no matter where it is in the hierarchy (..)

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

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.