首页 > 解决方案 > 为什么 c# ReadXml 返回错误的数据?

问题描述

我正在缓存数据以减少 SQL Server 活动。

当我第一次从 SQL Server 请求数据时,我会使用WriteXml它来将其存储在磁盘上。

然后第二次请求它(即一个名为cacheName存在的文件),我用ReadXml.

SQL Server 中的数据只有一行,utcDT 值为“2012-03-25 02:01”,当我在代码点 1 Test1() 处编写 DataTable 时,显示只有一行。当我手动检查磁盘上的 Xml 文件时,我也只看到 1 行。

但是,ReadXml在代码点 2 处读取后Test1()显示 2 个这样的行!

这是怎么回事?

public static DataTable FetchCache()
{
    var cacheName = @"C:\MyCache.xml";

    if (File.Exists(cacheName))
    {
        var ds = new DataSet();
        var fs = new FileStream(cacheName, FileMode.Open, FileAccess.Read, FileShare.Read);

        using (var sr = new StreamReader(fs))
        {
            ds.ReadXml(sr, XmlReadMode.ReadSchema);
        }

        table = ds.Tables[0];
        Test1(table);  //Code point 2
    }
    else
    {
        table = FetchDataTable(connectionString, sqlCommand, nullOnError: nullOnError);
        Test1(table); //Code point 1
        table.WriteXml(cacheName, XmlWriteMode.WriteSchema);
    }

    return table;
}

public static void Test1(DataTable table)
{
    var rows = table.AsEnumerable()
                    .Where(x => x.Field<DateTime>("utcDT").Equals(new DateTime(2012, 03, 25, 02, 01, 00)))
                    .ToArray();
}

public static DataTable FetchDataTable(string connectionString, string sqlCommand, bool nullOnError= false)
{
    DataSet ds = new DataSet();
    DataTable dt = new DataTable();

    try
    {
        using (SqlConnection conn = new SqlConnection(connectionString))
        {
            conn.Open();

            SqlDataAdapter da = new SqlDataAdapter(sqlCommand, conn);
            da.SelectCommand.CommandTimeout = 600;
            ds.Reset();

            da.Fill(ds);
            dt = ds.Tables[0];
        }
    }
    catch (Exception err)
    {
        if (nullOnError)
            return dt;

        throw new Exception("[Utils.MsSQLS.FetchDataTable] Could not get data: " + err.Message);
    }

    return dt;
}

标签: c#sql-server

解决方案


以防万一其他人有同样的问题。我找到了答案。

我的 SQL 表 DateTime 列最初指定为 UnspecifiedLocal,但它们包含的数据实际上是 UTC。

为了将缓存保存为 Xml,我必须从我从 SQL 获取的表中创建一个新的 DataTable 克隆,并将 DateTimeMode 更改为 UTC ,然后我从旧表复制到新表(使用 ItemArray 副本逐行)。

这很麻烦,但解决了这个问题。


推荐阅读