将数据表列映射到datetime2字段时精度损失

时间:2016-12-07 10:43:54

标签: .net sql-server precision datetime2

背景

字段TimestampCreation在DB中创建:

[TimestampCreation] [datetime2](7) NOT NULL

如果我将字段添加到这样的数据表:

table.Columns.Add(new DataColumn("TimestampCreation", typeof(DateTime)));

该值失去精度,因为它的存储方式如下:

2016-12-07 11:38:39.4990000

什么时候应该

2016-12-07 11:38:39.4998426

我试过的一个解决方案

如果我像这样添加列:

table.Columns.Add(new DataColumn("TimestampCreation", typeof(string))); // Actually datetime2

该值正确存储到DB,但这感觉很脏/很糟糕。

代码中的用法

值设置如下:

public static void AddToTable(this EntityDto source, DataTable table)
{
    var row = table.NewRow();

    ...
    ...
    row["TimestampLastModification"] = source.TimestampLastModification;

    table.Rows.Add(row);
}

source.TimestampLastModification的类型为DateTime

public DateTime TimestampLastModification { get; set; }

接下来,数据表将保存到存储中,如下所示:

Root.PluginManager().PersistentStorage(ParametersHelper.OverallSchema).Insert(ref table)

问题

datetime2字段添加到数据列并保持预期精度的正确方法是什么?

1 个答案:

答案 0 :(得分:0)

我找到了一个解决方案,这是我自己的事情,而不是第三方依赖。我通过在查询中将日期转换为nvarchar来修复它:

<div id="graph"></div>
    function barChartPlotter(e) {
    var myColor = ["#ECD078", "#D95B43", "#C02942", "#542437", "#53777A", "#42d7f4", "red", "green"];
    var myColor1 = ["black", "red", "green", "#ECD078", "#D95B43", "#C02942", "#542437", "#53777A"];
    var ctx = e.drawingContext;
    var points = e.points;
    var y_bottom = e.dygraph.toDomYCoord(0);

    // This should really be based on the minimum gap
    var bar_width = 2 / 3 * (points[1].canvasx - points[0].canvasx);
    // a lighter shade might be more aesthetically pleasing

    // Do the actual plotting.
    for (var i = 0; i < points.length; i++) {
        var p = points[i];
        var center_x = p.canvasx; // center of the bar
        ctx.fillStyle = myColor[i];
        ctx.fillRect(center_x - bar_width / 2, p.canvasy, bar_width, y_bottom - p.canvasy);
        ctx.strokeRect(center_x - bar_width / 2, p.canvasy, bar_width, y_bottom - p.canvasy);
    }
    for (var i = 0; i < points.length; i++) {
        var p = points[i];
        console.log(points[1]);
        var center_x = p.canvasx; // center of the bar
        ctx.fillStyle = myColor1[i];
        ctx.fillRect(center_x - bar_width / 2, p.canvasy, bar_width, (y_bottom - p.canvasy) / 2);
        ctx.strokeRect(center_x - bar_width / 2, p.canvasy, bar_width, (y_bottom - p.canvasy) / 2);
    }
}
g = new Dygraph(document.getElementById("graph"),
    "X,Y\n" +
    "1,2\n" +
    "2,4\n" +
    "3,6\n" +
    "4,8\n" +
    "5,10\n" +
    "6,12\n" +
    "7,14\n" +
    "8,16\n", {
        // options go here. See http://dygraphs.com/options.html
        legend: 'always',
        animatedZooms: true,
        plotter: barChartPlotter,
        dateWindow: [0, 9]
    });

接下来,我通过代码将字符串转换为日期时间:

SELECT CONVERT(VARCHAR, [TimestampLastModification], 126) [TimestampLastModification]
FROM ...

奇怪的是,将对象(实际上是DateTime类型)转换为DateTime会导致精度损失,但上述方法确实有效。