【问题标题】:accessing array from datatable column in c#从 C# 中的数据表列访问数组
【发布时间】:2018-10-15 07:23:09
【问题描述】:

我有一个如下所示的数据表,其中包含几列。数据表列之一的值为 json 数组 ( Contacts )。我想从列中访问name 属性。

Name     ID    Contacts 
User1    1     [{ "id": 1, "name": "User3", } }]]

【问题讨论】:

  • 数据库列不包含数组。很可能您的意思是 Contacts 包含一个 JSON 字符串。使用 JSON.NET 或其他 JSON 序列化程序来读取内容。
  • 您使用的是哪个数据库? SQL Server 2016+ 和 PostgreSQL 具有 JSON 函数,这意味着您可以只提取联系人姓名而不是整个对象。否则,您将不得不反序列化 JSON 字符串并读取 name
  • 它是一个带有 json 的数据表(转换为字符串)。
  • @PanagiotisKanavos 这不是真的。 Postgresql 有数组,但只有简单的一维。
  • @daremachine 什么不是真的? Postgres 支持 JSON 吗?这个数据看起来像 JSON?我们是否真的需要开始讨论 SQL、语言与每个供应商引入的自定义以及索引和查询多值字段的难易程度,即使它们可用?从而使多值列即使可用也有问题?

标签: c# arrays json datatable


【解决方案1】:

此表包含 JSON 字符串,而不是数组。要获取该字段的内容,必须使用 JSON.NET 对其进行反序列化并读取其内容,例如:

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

JsonConvert.DeserializeObject 可以将 JSON 字符串反序列化为具体类型或动态对象。在此示例中,内容被反序列化为包含数组的动态对象。 contacts[0].name 将返回第一个元素的名称属性。

在这种情况下,最好创建一个具体类型而不是使用动态:

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

这允许使用 LINQ 检索特定属性,例如:

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

使用 JSONPath

另一种选择是使用JSONPath 提取特定值而不解析整个字符串。

不是反序列化字符串,而是使用JArray.ParseJObject.Parse 解析。之后,SelectTokens 用于检索匹配查询路径的值:

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 表示

对于任何元素,返回任何名为 name 的属性,无论它在层次结构中的哪个位置 (..)

【讨论】:

    猜你喜欢
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 2014-11-06
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多