【问题标题】:SQL data to custom JSON.net structureSQL 数据到自定义 JSON.net 结构
【发布时间】:2016-05-31 05:29:04
【问题描述】:

大家好,我有以下 SQL 查询,输出以下内容:

ID  | Name    | theRole | THrs | Mon   |....| trainH1 | train58 | train52 | train05 |etc...
===========================================================================================
152 | BOB M.  | Admin   | 40   | 1-9pm |....| 168dGrc0 | 89220E | 2FDEx56 | 5569CCz |......

理想情况下,我希望结构看起来像这样 [注意:下面有其他表名]:

{
    "scheduleName": "",
    "firstName": "",
    "lastName": "",
    "theRole": "",
    "linker": "",
    "Schedule": {
        "ID": "",
        "totalHrs": "",
        "Mon": "",
        "Tue": "",
        "Wed": "",
        "Thu": "",
        "Fri": "",
        "Sat": ""
    },
    "empInfo": {
        "ID": "",
        "Email": "",
        "Phone": "",
        "Active": "",
        "Img": "",
        "Badge": ""
    },
    "availability": {
        "ID": "",
        "Mon": "",
        "Tue": "",
        "Wed": "",
        "Thu": "",
        "Fri": "",
        "Sat": ""
    },
    "training": {
        "?": "?"
    }
}

火车是我遇到问题的地方。数据库中的这些值可以在任何给定时间更改名称或添加或删除。目前我有大约 35 个值。因此,我无法像使用 IDName 那样在我的 类函数硬编码这些值、角色THrs等...

VB.net 类定义到目前为止如下所示:

Public Class Schedule
    Private m_ID As String
    Private m_totalHrs As String
    Private m_Mon As String
    Private m_Tue As String
    Private m_Wed As String
    Private m_Thu As String
    Private m_Fri As String
    Private m_Sat As String

    Public Property ID() As String
        Get
            Return m_ID
        End Get
        Set
            m_ID = Value
        End Set
    End Property

    Public Property totalHrs() As String
        Get
            Return m_totalHrs
        End Get
        Set
            m_totalHrs = Value
        End Set
    End Property

    Public Property Mon() As String
        Get
            Return m_Mon
        End Get
        Set
            m_Mon = Value
        End Set
    End Property

    Public Property Tue() As String
        Get
            Return m_Tue
        End Get
        Set
            m_Tue = Value
        End Set
    End Property

    Public Property Wed() As String
        Get
            Return m_Wed
        End Get
        Set
            m_Wed = Value
        End Set
    End Property

    Public Property Thu() As String
        Get
            Return m_Thu
        End Get
        Set
            m_Thu = Value
        End Set
    End Property

    Public Property Fri() As String
        Get
            Return m_Fri
        End Get
        Set
            m_Fri = Value
        End Set
    End Property

    Public Property Sat() As String
        Get
            Return m_Sat
        End Get
        Set
            m_Sat = Value
        End Set
    End Property
End Class

Public Class EmpInfo
    Private m_ID As String
    Private m_Email As String
    Private m_Phone As String
    Private m_Active As String
    Private m_Img As String
    Private m_Badge As String

    Public Property ID() As String
        Get
            Return m_ID
        End Get
        Set
            m_ID = Value
        End Set
    End Property

    Public Property Email() As String
        Get
            Return m_Email
        End Get
        Set
            m_Email = Value
        End Set
    End Property

    Public Property Phone() As String
        Get
            Return m_Phone
        End Get
        Set
            m_Phone = Value
        End Set
    End Property

    Public Property Active() As String
        Get
            Return m_Active
        End Get
        Set
            m_Active = Value
        End Set
    End Property

    Public Property Img() As String
        Get
            Return m_Img
        End Get
        Set
            m_Img = Value
        End Set
    End Property

    Public Property Badge() As String
        Get
            Return m_Badge
        End Get
        Set
            m_Badge = Value
        End Set
    End Property
End Class

Public Class Availability
    Private m_ID As String
    Private m_Mon As String
    Private m_Tue As String
    Private m_Wed As String
    Private m_Thu As String
    Private m_Fri As String
    Private m_Sat As String

    Public Property ID() As String
        Get
            Return m_ID
        End Get
        Set
            m_ID = Value
        End Set
    End Property

    Public Property Mon() As String
        Get
            Return m_Mon
        End Get
        Set
            m_Mon = Value
        End Set
    End Property

    Public Property Tue() As String
        Get
            Return m_Tue
        End Get
        Set
            m_Tue = Value
        End Set
    End Property

    Public Property Wed() As String
        Get
            Return m_Wed
        End Get
        Set
            m_Wed = Value
        End Set
    End Property

    Public Property Thu() As String
        Get
            Return m_Thu
        End Get
        Set
            m_Thu = Value
        End Set
    End Property

    Public Property Fri() As String
        Get
            Return m_Fri
        End Get
        Set
            m_Fri = Value
        End Set
    End Property

    Public Property Sat() As String
        Get
            Return m_Sat
        End Get
        Set
            m_Sat = Value
        End Set
    End Property
End Class

Public Class Training
    Private m_something1 As String
    Private m_something2 As String
    Private m_something3 As String

    Public Property something1() As String
        Get
            Return m_something1
        End Get
        Set
            m_something1 = Value
        End Set
    End Property

    Public Property something2() As String
        Get
            Return m_something2
        End Get
        Set
            m_something2 = Value
        End Set
    End Property

    Public Property something3() As String
        Get
            Return m_something3
        End Get
        Set
            m_something3 = Value
        End Set
    End Property
End Class

Public Class RootObject
    Private m_scheduleName As String
    Private m_firstName As String
    Private m_lastName As String
    Private m_theRole As String
    Private m_linker As String
    Private m_Schedule As Schedule
    Private m_empInfo As EmpInfo
    Private m_availability As Availability
    Private m_training As Training

    Public Property scheduleName() As String
        Get
            Return m_scheduleName
        End Get
        Set
            m_scheduleName = Value
        End Set
    End Property

    Public Property firstName() As String
        Get
            Return m_firstName
        End Get
        Set
            m_firstName = Value
        End Set
    End Property

    Public Property lastName() As String
        Get
            Return m_lastName
        End Get
        Set
            m_lastName = Value
        End Set
    End Property

    Public Property theRole() As String
        Get
            Return m_theRole
        End Get
        Set
            m_theRole = Value
        End Set
    End Property

    Public Property linker() As String
        Get
            Return m_linker
        End Get
        Set
            m_linker = Value
        End Set
    End Property

    Public Property Schedule() As Schedule
        Get
            Return m_Schedule
        End Get
        Set
            m_Schedule = Value
        End Set
    End Property

    Public Property empInfo() As EmpInfo
        Get
            Return m_empInfo
        End Get
        Set
            m_empInfo = Value
        End Set
    End Property

    Public Property availability() As Availability
        Get
            Return m_availability
        End Get
        Set
            m_availability = Value
        End Set
    End Property

    Public Property training() As Training
        Get
            Return m_training
        End Get
        Set
            m_training = Value
        End Set
    End Property
End Class

当我不知道数据名称是什么时,如何为 json.net 创建一个序列化结构?我正在考虑一种 List(as String) 甚至是 Dictionary(String, String) 但仍然不确定如何将它们添加到类中并填充它使用这些值的 sql 数据。

这就是我要问的:

(1) 当我不知道这些表名是什么时,如何让类结构接受 sql 列名和值?

(2) 能够从类函数中的数据中形成我想要的json结构。

【问题讨论】:

  • 您现在如何读取 SQL 数据以获取您知道名称的其他值?
  • 只使用常规的 SQLReader 循环。

标签: sql-server json vb.net json.net


【解决方案1】:

最初我认为Dictionary(Of String, String) 非常适合此操作,但您的 cmets 已经清楚地表明,训练项目可能存在重复的列名。因此,字典在这里不起作用,而且您想要的 JSON 格式也不起作用。您需要将 JSON 的 training 部分更改为对象数组,以便处理潜在的重复项。

我认为你可以这样做:

  1. Training 类更改为具有两个公共属性NameValue

  2. 在您的RootObject 类中,将training 属性定义为List(Of Training) 而不是单个Training

    Public Class RootObject
        ...
        Private m_training As List(Of Training)
    
        ...
        Public Property training() As List(Of Training)
            Get
                If m_training Is Nothing Then
                    m_training = New List(Of Training))
                End If
                Return m_training
            End Get
            Set(value As List(Of Training))
                m_training = value
            End Set
        End Property
    End Class
    
  3. 在您的 SQL 查询中,确保所有与训练相关的列在 SELECT 子句中排在最后。既然你说列名不共享一个共同的前缀,他们唯一能看到的识别它们的方法是按位置。

    SELECT ID, Name, theRole, THrs, Mon, ..., EMPTR.*
    FROM ...
    
  4. 在您的阅读器循环中,填充该行的所有已知属性后,您可以遍历阅读器中的剩余字段以填充该行的训练项目列表。

    Const firstTrainingColumnIndex As Integer = 5 'Adjust as necessary for your actual data '
    
    Dim i As Integer
    For i = firstTrainingColumnIndex To reader.FieldCount - 1
        trainingItem.Name = reader.GetName(i)
        trainingItem.Value = IIf(reader.IsDBNull(i), Nothing, reader.GetString(i))
        rootObj.training.Add(trainingItem)
    Next
    
  5. 要创建 JSON 输出,只需像往常一样进行序列化。 Json.Net 已经知道如何处理List

    Dim json as String = JsonConvert.SerializeObject(rootObj, Formatting.Indented)
    

    输出最终应该是这样的:

    {
      "scheduleName": "Bob M",
    
      ...
    
      "training": [
        {
          "Name": "trainH1",
          "Value": "168dGrc0"
        },
        {
          "Name": "train58",
          "Value": "89220E"
        },
        {
          "Name": "train52",
          "Value": "2FDEx56"
        },
        {
          "Name": "train05",
          "Value": "5569CCz"
        }
      ]
    }
    

【讨论】:

  • 很好的例子,布赖恩!但是,训练部分不会在所有行中都有“train”这个词,所以我不能随便找到它。有没有办法让行名作为它的循环?
  • 因为这是我要求获取所有数据的查询的一部分 [dbo].[training] As EMPTR。所以我称它为 EMPTR,在我的 select 中我有 EMPTR.*。是否可以获取起始EMPTR+columnName
  • 读者看到的列名是你的 SQL 查询中的任何内容。所以如果你做了select train58 as EMPTR,那么读者会看到EMPTR而不是train58。如果 EMPTR 是表(不是列)的别名,则不是,读者不会将表别名视为列名的一部分。要使用上述方法,您需要一些通用方法来识别与培训相关的列。如果你不能按名字做,你能按职位做吗?换句话说,你能让所有变量训练列都排在所有知名列之后吗? (续)
  • 如果你能做到,并且你知道有多少知名列,那么你可以在第一个训练列开始你的内部循环并将所有这些添加到字典中,直到没有还有更多列。
  • 如何处理多条记录?然后字典会告诉我该值已被使用?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-09-25
  • 1970-01-01
  • 2021-10-01
  • 2015-12-18
  • 2021-02-22
  • 2013-08-30
  • 1970-01-01
相关资源
最近更新 更多