繁体   English   中英

Npgsql DataReader 使用 DateTime 类型表示没有时区的时间而不是 TimeSpan

[英]Npgsql DataReader uses DateTime type for time without time zone rather than TimeSpan

我正在使用 Npgsql 从 Postgres 中的表中进行选择。 该表有一个auction_time列,它的类型是time without time zone 读者返回的数据表将此列auction_time转换为DateTime而不是我所期望的TimeSpan 当将数据批量复制到time(7)类型的 MS SQLServer 中的另一个表时,这会导致问题。

这是我选择的地方:

using (NpgsqlConnection connection = new NpgsqlConnection(String.Format(PropertyDataDB.ConnectionStringWithSearchPath, schemaName)))
{
    connection.Open();
    NpgsqlCommand command = new NpgsqlCommand
    {
        CommandText = commandText,
        Connection = connection
    };

    using (NpgsqlDataReader dataReader = command.ExecuteReader())
    {
        DataTable dt = new DataTable();
        //dt = dataReader.GetSchemaTable();
        dt.Load(dataReader);

        BulkCopy(destinationTable, dt);
    }
}

因此,dt 中的auction_type将是DateTime类型,并且所有时间都将日期1/1/0001附加到它的前面。 我怎样才能防止这种情况?

谢谢。

另一个修复是将 Npgsql 升级到 3.x 版,此问题已修复。 http://www.npgsql.org/doc/release-notes/3.0.html

这就是我最终要做的,如果您需要继续使用 verison 2.x,请只做这样的事情。 它有效,但我根本不喜欢它。 我只是克隆数据表,更改数据类型,并在需要时执行“强制转换”。

using (NpgsqlConnection connection = new NpgsqlConnection(String.Format(PropertyDataDB.ConnectionStringWithSearchPath, schemaName)))
{
    connection.Open();
    NpgsqlCommand command = new NpgsqlCommand
    {
        CommandText = commandText,
        Connection = connection
    };

    using (NpgsqlDataReader dataReader = command.ExecuteReader())
    {
        DataTable dt = new DataTable();
        dt.Load(dataReader);

        if (dt.Columns.Contains("auction_time"))
        {
            DataTable clone = dt.Clone();
            clone.Columns["auction_time"].DataType = typeof(TimeSpan);
            foreach (DataRow row in dt.Rows)
            {
                DataRow newRow = clone.NewRow();
                foreach (DataColumn column in dt.Columns)
                {
                    if (column.ColumnName == "auction_time" && !row.IsNull(column.Ordinal))
                    {
                        newRow[column.Ordinal] = ((DateTime)row[column.Ordinal]).TimeOfDay;
                    }
                    else
                    {
                        newRow[column.Ordinal] = row[column.Ordinal];
                    }
                }
            }
            dt = clone;
        }

        BulkCopy(destinationTable, dt);
    }
}

我的解决方案:

class Model
{
    public readonly static string tableName = "tb_name";
    public Int32 id {get; private set;}
    public string auth_token {get; private set;}
    public TimeSpan column_time {get; set;} // this is the target !!

    /* more columns for model object   here.. */

    public static NpgsqlCommand Query(string sql = null )
    {
        // treturn new NpgsqlCommand from my global NpgsqlConnection  definition
        return Connection.CreateObject().Query(sql); 
    }

    public static Model FindByPk(int id)
    {
        NpgsqlCommand query = Query(string.Format("select  * from {0} where id = @id order by id asc limit 1" , tableName ));
        query.Parameters.AddWithValue("@id", id);

        NpgsqlDataReader reader = query.ExecuteReader();
        if(reader.HasRows == false)
            return null;

        Model obj = new Model();
        return (obj.SetDbProperties(reader)) ? obj : null;
    }

    protected bool SetDbProperties(NpgsqlDataReader reader)
    {
        if(reader.IsClosed)
            return false;
        try{
            reader.Read();

            for (int i = 0; i < reader.FieldCount; i++)
            {
                string key = reader.GetName(i);

                if(reader.GetValue(i) == DBNull.Value )
                    continue;

                //@todo add dinamic setter by key value
                // https://titiandragomir.wordpress.com/2009/12/22/getting-and-setting-property-values-dynamically/
                switch(key)
                {
                    case "id":
                        this.id =  reader.GetInt32(i);
                        break;
                    case "auth_token":
                        this.auth_token = reader.GetString(i);
                        break;

                    case "column_time":
                            // solution!!!!
                            var colValue = reader.GetTime(i);
                            this.horario_dia1_init = new TimeSpan(0, colValue.Hours , colValue.Minutes, colValue.Seconds, colValue.Microseconds ); 
                        break;
                }
            }
            reader.Close();
            return true;
        }
        catch(Exception e){
            Console.WriteLine(e.Message);
            return false;
        }
    }
}

使用示例:

    public static void Main(string[] args)
    {

        Model model = Model.FindByPk(1);
        if(model == null)
            Console.WriteLine("record not found");

        else {
            Console.WriteLine("model.id               {0}", model.id);
            Console.WriteLine("model.auth_token       {0}", model.auth_token);
            Console.WriteLine("model.column_time      {0}", model.column_time); 
        }

        Console.Read();
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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