2017-03-02 64 views
1

「對於JSON AUTO」 我從SqlServer的2016使用返回的Json我op是這樣駝峯JSONObject的數組中的sql server2016

"[{\"Id\":3,\"SId\":\"5801\",\"Name\":\"Pizza\",\"Type\":\"Error\"}]" 

我使用下面的代碼

public Someclass GetData(int Id) 
    { 
     using (var dataContext = new DataContext(_connectionString)) 
     { 
       var serializer = new JsonSerializerSettings() 
       { 
       ContractResolver = new CamelCasePropertyNamesContractResolver() 
       }; 
      var dataArray = dataContext.ExecuteQuery<string>(query.ToString()).SingleOrDefault(); 
      dynamic obj= JsonConvert.DeserializeObject<dynamic>(dataArray , serializer); 

      return obj 
     } 
    } 

反序列化數據在我不明白駝峯格式data.It OBJ對象是以下格式

"{[{"Id":3,SId":"5801","Name":"Pizza","Type":"Error"}]}" 

由於我的數據結構保持JSON結果是動態的,我無法使用json.net將其轉換爲camelcase。有沒有什麼sql方法返回從sql server 2016 camelcase列名稱2016

回答

-1

您發佈在問題的頂部和底部的JSON字符串之間有一個不同。

第一個JSON字符串是一個有效的JSON字符串,它表示一個對象數組。所以你需要將它反序列化爲如下的動態數組。

var json = "[{\"Id\":3,\"SId\":\"5801\",\"Name\":\"Pizza\",\"Type\":\"Error\"}]"; 
var serializer = new JsonSerializerSettings() 
{ 
    ContractResolver = new CamelCasePropertyNamesContractResolver() 
}; 
dynamic[] obj = JsonConvert.DeserializeObject<dynamic[]>(json, serializer); 

Console.WriteLine("Id : {0}", obj[0].Id); 
Console.WriteLine("Sid : {0}", obj[0].SId); 
Console.WriteLine("Name : {0}", obj[0].Name); 
Console.WriteLine("Type : {0}", obj[0].Type); 

帖子底部的JSON字符串不是有效的JSON。我希望這是一個錯字。

+0

這種解決方案不能轉換爲駝峯。我想要屬性Id,Sid被camelcased即id,sid,名稱 – pankaj

+1

JSON反序列化不會更改目標屬性名稱或它的大小寫。由於您的目標類型是動態的,因此它將使用與JSON字符串中相同的屬性名稱和外殼。如果你想要屬性名稱和自己的方式,那麼你需要定義一個具有用JsonProperty屬性裝飾的屬性的類。 –

+1

'JsonSerializerSettings'用於在序列化時序列化和正確讀取屬性名稱的同時生成具有所需外殼的JSON字符串。我不會更改它的反序列化類型的屬性的名稱或大小寫。 –

0

他們希望從 「選擇...的JSON汽車」 這個JSON輸出:

[{ 「ID」:3, 「SID」: 「5801」, 「名」: 「比薩」,「類型「:」Error「}]

如果您直接在JavaScript中使用SQL輸出,您可能會在意它不是駱駝大小寫。但是,在上面的代碼中,SQL正在.NET程序中使用,.NET反序列化不區分大小寫。沒有必要使用動態類型或與串行器設置混亂。只需直接反序列化SomeClass

var someClass = JSONConvert.DeserializeObject<SomeClass>(dataArray)

但需要注意的是,你應該在C#代碼中使用C#約定 - 所以SomeClass的應該用Pascal大小寫的名字。如果您從.NET WebApi返回SomeClass,則應該將其轉換爲駝峯大小寫,即。在.NET Core中,這是默認完成的。對於.NET Framework,您可以在應用程序初始化時更改JSON序列化程序設置,以執行同樣的操作。

但如果你真的想:如果可以的話

[{"id":3,"sId":"5801","name":"pizza","type":"Error"}]

修改查詢本身並明確列出在什麼情況下,你想要的列:

select id, sId, name, type from ... for json auto

1

我寫了一個存儲程序來完成任意JSON到camelcase的轉換。它涵蓋了我能想到的大多數數據類型,但可能有一些JSON會打破它。我希望它是一個函數,但是你不能在一個函數中執行動態sql。

CREATE PROCEDURE [dbo].[CamelCaseJson] (
    @jsonIn nvarchar(max), 
    @jsonOut nvarchar(max) output 
) 
AS 
BEGIN 
    SET NOCOUNT ON 

    DECLARE @isArray BIT = 0 
    DECLARE @innerCols NVARCHAR(MAX) 
    DECLARE @outerCols NVARCHAR(MAX) 
    DECLARE @sql  NVARCHAR(MAX) 

    IF LEFT(@jsonIn, 1) = '[' 
    BEGIN 
     SET @isArray = 1 
    END 

    CREATE TABLE #tmpData (
     [rownum]   INT IDENTITY(1, 1), 
     [key]    NVARCHAR(MAX), 
     [value]    NVARCHAR(MAX), 
     [type]    INT, 
     [processedKey]  NVARCHAR(MAX), 
     [processedValue] NVARCHAR(MAX) 
    ) 

    DECLARE @jsons TABLE (
     [rownum] INT, 
     [json]  NVARCHAR(MAX) 
    ) 

    INSERT #tmpData (
     [key], 
     [value], 
     [type], 
     [processedKey], 
     [processedValue] 
    ) 
    SELECT 
     [key], 
     [value], 
     [type], 
     LOWER(SUBSTRING([key], 1, 1)) + SUBSTRING([key], 2, 999999999), 
     [value] 
    FROM OPENJSON(@jsonIn) 


    INSERT @jsons (
     [rownum], 
     [json] 
    ) 
    SELECT 
     [rownum], 
     [value] 
    FROM #tmpData 
    WHERE [type] in (4, 5) 


    DECLARE @id   INT 
    DECLARE @subJsonIn NVARCHAR(MAX) 
    DECLARE @subJsonOut NVARCHAR(MAX) 

    WHILE EXISTS (SELECT 1 FROM @jsons) 
    BEGIN 
     SET @subJsonOut = NULL 

     SELECT 
      TOP 1 
      @id = [rownum], 
      @subJsonIn = [json] 
     FROM @jsons 

     EXEC [dbo].[CamelCaseJson] @subJsonIn, @subJsonOut OUTPUT 

     UPDATE #tmpData 
     SET [processedValue] = @subJsonOut 
     WHERE [rownum] = @id 

     DELETE @jsons WHERE [rownum] = @id 
    end 


    IF @isArray = 0 
    BEGIN 
     SELECT @innerCols = COALESCE(@innerCols + ', ', '') + QUOTENAME([processedKey]) FROM #tmpData 

     SELECT @outerCols = 
      COALESCE(@outerCols + ', ', '') 
       + CASE  
         WHEN [type] = 2 AND [value] LIKE '%e%' THEN 'CAST(' + QUOTENAME([processedKey]) + ' AS FLOAT) AS ' + QUOTENAME([processedKey]) 
         WHEN [type] = 2 AND [value] LIKE '%.%' THEN 'CAST(' + QUOTENAME([processedKey]) + ' AS DECIMAL(19, 7)) AS ' + QUOTENAME([processedKey]) 
         WHEN [type] = 2 THEN 'CAST(' + QUOTENAME([processedKey]) + ' AS INT) AS ' + QUOTENAME([processedKey]) 
         WHEN [type] = 3 THEN 'CAST(' + QUOTENAME([processedKey]) + ' AS BIT) AS ' + QUOTENAME([processedKey]) 
         WHEN [type] in (4, 5) THEN 'JSON_QUERY(' + QUOTENAME([processedKey]) + ') AS ' + QUOTENAME([processedKey]) 
         ELSE QUOTENAME([processedKey]) 
        END 
     FROM #tmpData 


     SET @sql = ' 
      WITH pv AS (
       SELECT 
        [dummy] = 1, 
        [key] = [processedKey], 
        [value] = [processedValue] 
       FROM #tmpData 
      ) 
      SELECT @dynout = (
       SELECT ' + @outerCols + ' 
       FROM (
        SELECT [dummy], ' + @innerCols + ' 
        FROM pv 
        PIVOT (
         MAX([value]) FOR [key] IN (' + @innerCols + ') 
        ) pvresult 
       ) x 
       FOR JSON PATH, WITHOUT_ARRAY_WRAPPER, INCLUDE_NULL_VALUES 
      ) 
     ' 

     EXEC sp_executesql @sql, N'@dynout NVARCHAR(MAX) OUT', @jsonOut OUTPUT 
    END 
    ELSE 
    BEGIN 
     SELECT @jsonOut = 
      COALESCE(@jsonOut + ',', '') + 
       CASE 
        WHEN [type] = 1 THEN '"' + [processedValue] + '"' 
        ELSE [processedValue] 
       END 
     FROM #tmpData 
     ORDER BY [rownum] 

     SET @jsonOut = '[' + @jsonOut + ']' 
    END 

    DROP TABLE #tmpData 
END 
GO 

要檢查你的例子:

DECLARE @jsonIn  NVARCHAR(MAX) 
DECLARE @jsonOut NVARCHAR(MAX) 


SET @jsonIn = (
    SELECT 
     [Id] = 3, 
     [SId] = '5801', 
     [Name] = 'Pizza', 
     [Type] = 'Error' 
    FOR JSON PATH 
) 

EXEC [dbo].[bh_CamelCaseJson] @jsonIn, @jsonOut OUTPUT 

SELECT @jsonIn [Json] 
UNION ALL 
SELECT @jsonOut [Json] 

給你

在[{ 「ID」:3, 「SID」: 「5801」, 「姓名」:「比薩「]」Type「:」Error「}]

Out [{」id「:3,」sId「:」5801「,」name「:」Pizza「,」type「:」Error「}]

我的單元測試JSON(不漂亮格式化的,不好意思):

{"Pnull":null,"Pstring":"Foo","Pint":1,"Pdec":1.3,"Pbool":true,"Pstrarray":["a","b"],"Pintarray":[1,3,5],"Parray":[{"Prop":"val1"},{"Prop":"val2"}],"Pjson":{"Subproperty":1},"Pjsonstring":"{\"Subproperty\":2}","Poffset":"2017-06-20T22:18:31.2279221-04:00","DeepObj":{"Level":2,"Sub":{"Level":3,"Sub":{"Level":4,"Sub":{"Level":"Basement"}}}},"Flt":1.3e-9}