【问题标题】:Save DataTable to file where column type is list(of KeyValuePair...)将 DataTable 保存到列类型为列表的文件(KeyValuePair ...)
【发布时间】:2017-06-06 04:09:31
【问题描述】:

我正在为一家餐馆构建 SMS 订购服务,但难以准确地将 Datatable 保存到文件中,该文件稍后会在程序重新启动时加载。

我的表包含一个名为“MessageHistory”的列,其类型为 List(of KeyValuePair),它被保存为空。

我的桌子是这样的:

Clients.Columns.AddRange(New DataColumn() {
        New DataColumn("CodedPhoneNumber", GetType(String)),
        New DataColumn("FriendlyPhoneNumber", GetType(String)),
        New DataColumn("Name", GetType(String)),
        New DataColumn("CurrentOrder", GetType(String)),
        New DataColumn("OrderHistory", GetType(String)),
        New DataColumn("TabBalance", GetType(Int32)),
        New DataColumn("MessageHistory", GetType(List(Of KeyValuePair(Of DateTime, String))))})

表格保存到文件中:

 Dim stream As New System.IO.MemoryStream()
    Dim formatter As System.Runtime.Serialization.IFormatter = New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter()
    formatter.Serialize(stream, Clients)

    Dim TableBytes As Byte() = stream.GetBuffer()

    File.WriteAllBytes(FilePath, TableBytes) 

在保存之前,我的带有 KeyValuePairs 的列看起来像这样(抱歉,还没有足够的声誉来嵌入图片):

MessageHistory in RAM

保存的文件将该列注册为:

<MessageHistory xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <KeyValuePairOfDateTimeString />
    <KeyValuePairOfDateTimeString />
    <KeyValuePairOfDateTimeString />
    <KeyValuePairOfDateTimeString />
  </MessageHistory>

由于 XML 是空的,在将表加载回程序时,它会将每个条目复制为默认的 Datetime 值,而没有其他任何内容。

所以我的问题是,如果列不是简单地由一维字母数字值组成(所有其他列保存和加载正常),是否有更好的方法来保存表?

随着我的程序的发展,此表可能会包含其他数组列类型。

谢谢大家

【问题讨论】:

  • 试试这个:Clients.WriteXml("filename", XmlWriteMode.WriteSchema);
  • DataTable 似乎是一个奇怪的选择,这是什么原因?序列化代码存在多个问题
  • 可以使用简单的POCO对象列表,使用JSON序列化,效率会更高。
  • @jdweng,该代码产生了相同的结果。为简单起见,我选择了数据表而不是 SQL 服务器。由于该表可以轻松保存所有信息,并且每个衍生的 SMS 对话都可以启动一个带有 Datarow 变量的类,该变量保存重新插入主表的所有信息,因此感觉非常适合,无需外部应用程序。我没有意识到节省桌子会成为一个问题。我以为它只是 RAM 中保存的二进制字节表示。显然我错了。
  • 您的结果有架构吗?是的,结果可能是相同的,但是具有架构然后使用 Client.ReadXml("filename") 方法应该会给出正确的结果。架构将读取与保存时相同的数据。

标签: xml vb.net datatable save keyvaluepair


【解决方案1】:

这是我想出的解决方案。它并不优雅,但它确实有效。

我将 List(Of KeyValuePair(DateTime,String) 提取到这些列表的临时列表中,并将其保存到单独的文件中。

Dim MessageHistory As New List(Of List(Of KeyValuePair(Of DateTime, String)))

    For Each Row In Clients.Rows
        MessageHistory.Add(Row("MessageHistory"))
    Next

    Dim Stream2 As New System.IO.MemoryStream()
    formatter.Serialize(Stream2, MessageHistory)

    Dim HistoryBytes As Byte() = Stream2.GetBuffer
    File.WriteAllBytes(MessageHistoryPath, HistoryBytes)

然后我分别加载原始表和 MessageHistory,并重新整合它们。

        Dim FileBytes As Byte() = File.ReadAllBytes(ClientFilePath)
        Dim stream As New System.IO.MemoryStream(FileBytes)
        Dim formatter As System.Runtime.Serialization.IFormatter = New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter()

        Clients = DirectCast(formatter.Deserialize(stream), DataTable)

        FileBytes = File.ReadAllBytes(MessageHistoryPath)
        Dim stream2 As New System.IO.MemoryStream(FileBytes)

        Dim MessageHistory As New List(Of List(Of KeyValuePair(Of DateTime, String)))
        MessageHistory = DirectCast(formatter.Deserialize(stream2), List(Of List(Of KeyValuePair(Of DateTime, String))))

        For i = 0 To Clients.Rows.Count - 1
            Clients.Rows(i).Item("MessageHistory") = (MessageHistory(i))
        Next

【讨论】:

    猜你喜欢
    • 2015-02-28
    • 1970-01-01
    • 2015-02-07
    • 2020-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多