如何将子JSON结构转换为C#对象图
我正在使用SQL Server 2016的FOR JSON将SQL Server SELECT语句转换为JSON字符串。我的意图是让C#将生成的JSON字符串转换为对象。如何将子JSON结构转换为C#对象图
SQL Server服务器select语句:
SELECT
Id AS PersonId,
FirstName,
LastName,
Name,
Birthday,
(
SELECT
PhoneNumber.PhoneNumberTypeId,
PhoneNumber.PhoneNumber
FROM
PhoneNumber
INNER JOIN PhoneNumberType ON PhoneNumber.PhoneNumberTypeId = PhoneNumberType.Id
WHERE
PhoneNumber.PersonId = Person.Id
FOR JSON PATH,INCLUDE_NULL_VALUES
) AS PhoneNumberList
FROM
Person
ORDER BY
LastName
FOR JSON PATH,INCLUDE_NULL_VALUES
C#对象我试图将数据转换为:
public class PersonDataContract : IPersonDataContract
{
public Int32 PersonId { get; set; }
public String FirstName { get; set; }
public String LastName { get; set; }
public String Name { get; set; }
public DateTime? Birthday { get; set; }
public Int32 Age { get; }
public IList<IPhoneNumberDataContract> PhoneNumberList { get; set; }
public PersonDataContract()
{
PhoneNumberList = new List<IPhoneNumberDataContract>();
}
}
生JSON:
[
{
"PersonId": 5,
"FirstName": "Squire",
"LastName": "Escrow",
"Name": "Squire Escrow",
"Birthday": "2001-12-12",
"PhoneNumberList": "[{\"PhoneNumberTypeId\":1,\"PhoneNumber\":\"8129091423\"}]"
},
{
"PersonId": 6,
"FirstName": "Vilhelm",
"LastName": "Huldsputh",
"Name": "Vilhelm Huldsputh",
"Birthday": "1953-11-13",
"PhoneNumberList": "[{\"PhoneNumberTypeId\":1,\"PhoneNumber\":\"9871237171\"},{\"PhoneNumberTypeId\":2,\"PhoneNumber\":\"8189991212\"}]"
}
]
代码转换原始JSON到对象:
...
using (DbDataReader reader = command.ExecuteReader(CommandBehavior.CloseConnection))
{
while (reader.Read())
{
var jsonString = reader.GetValue(0).ToString();
var list = JsonConvert.DeserializeObject<List<PersonDataContract>>(jsonString);
}
reader.Close();
}
这个过程的工作,只要我从生JSON删除PhoneNumberList。我认为问题是我在我的SQL语句中使用了2'FOR JSON PATH(一个用于PhoneNumberList本身,另一个用于整个SELECT语句),这导致PhoneNumberList被转换为一个没有被转换成一个字符串的字符串阵列。
如何将表示电话号码集合的子字符串转换为IPhoneNumberDataContract数组?
这是排序覆盖the FAQ:
问题。我有JSON文本存储在表列中。我想将它包含在
FOR JSON
的输出中。但FOR JSON
逃脱在JSON所有 字符,所以我得到一个JSON字符串,而不是一个 嵌套的对象[..]答案。存储在文本列或文字中的JSON与任何文本一样被对待。也就是说,它被双引号包围并逃脱。如果 要返回转义的JSON对象,通过JSON列 的一个参数
JSON_QUERY
函数[..]
它没有明确提到使用FOR JSON
也将任何不平凡的子查询产生一个转义值,并以这种方式要求JSON_QUERY
。因此,使用
SELECT
Id AS PersonId,
FirstName,
LastName,
Name,
Birthday,
JSON_QUERY(
SELECT
...
FOR JSON PATH,INCLUDE_NULL_VALUES
) AS PhoneNumberList
通过“不平凡”,我的意思是,像这样的查询会不要求JSON_QUERY
:
SELECT
'Foo' AS Foo, (
SELECT 1 AS A
FOR JSON PATH
) AS Bar
FOR JSON PATH
Bar
这里将不再逃脱,因为优化显然会记住它的处理JSON。我还没有找到一套统一的规则来管理这个(different question, same issue),并且它甚至不清楚这是否是有意的行为或错误,但JSON_QUERY
不管你怎么做。它可能总是被使用,以防止查询从“简单”到“复杂”并突然需要它的意外。
'...生日,JSON_QUERY(SELECT ...)'。 –
将PersonDataContract的PhoneNumberList设置为字符串,然后将每个字符串反序列化为PhoneNumberDataContract。 –
@JeroenMostert - 你的建议解决了这个问题。你能回答这个问题吗?我可以接受它。谢谢。 –