简体   繁体   中英

Why is c# ReadXml returning wrong data?

I am caching data to decrease SQL Server activity.

When I fetch data from SQL Server the first time it is requested, I then use WriteXml to store it on disk.

Then second time it is requested (ie a file called cacheName exists), I fetch the data with ReadXml .

The data in SQL Server has only one row with utcDT value of '2012-03-25 02:01' and when I write the DataTable at Code point 1 Test1() shows there is only one row. When I manually inspect Xml file on disk I also see only 1 row.

However, after reading with ReadXml at code point 2 Test1() shows 2 such rows!

How is this happening?

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;
}

Just in case anyone else has same issue. I found the answer.

My SQL table DateTime columns were originally specified as UnspecifiedLocal, but the data they contain is actually UTC.

In order to save to cache as Xml, I have to create a new DataTable clone from table I fetch from SQL, and change DateTimeMode to UTC , then I copy from the old table to the new (row by row using ItemArray copy).

This is cumbersome but gets rid of the issue.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM