Sql server 为什么AsNoTracking会影响日期时间精度?

Sql server 为什么AsNoTracking会影响日期时间精度?,sql-server,entity-framework-6,Sql Server,Entity Framework 6,给定以下代码: var dbRecords = _context.Alerts.AsNoTracking() .Where(a => a.OrganizationId == _authorization.OrganizationId) .ToList(); var dbRecords2 = _context.Alerts .Where(a =&g

给定以下代码:

var dbRecords = _context.Alerts.AsNoTracking()
                        .Where(a => a.OrganizationId == _authorization.OrganizationId)
                        .ToList();
var dbRecords2 = _context.Alerts
                         .Where(a => a.OrganizationId == _authorization.OrganizationId)
                         .ToList();

foreach (var untrackedRecord in dbRecords) {
    var trackedRecord = dbRecords2.First(a => a.Id == untrackedRecord.Id);

    Assert.AreEqual(untrackedRecord.TimeStamp.Ticks, trackedRecord.TimeStamp.Ticks);
}
其中,时间戳数据存储在SQL Server 2012中定义为datetime2(0)的列中

断言失败,调试器将演示这两个刻度值始终不同

Expected: 636179928520000000 But was:  636179928523681935
未跟踪的值将始终四舍五入到最接近的秒(根据SQL存储的内容,这是预期的)。创建记录时,我保存的值来自DateTime.Now

再测试一些,对于我正在测试的每个对象,这似乎不是真的(不一致的刻度),只是对于我最近插入的记录。查看代码并给出列的定义方式,我不清楚为什么这很重要


现在,为了让我的测试通过,我只是将DateTime值与第二个值进行比较,这就是所需的全部内容。然而,我只是想了解为什么会发生这种情况:为什么我不能根据实体是否被跟踪来可靠地比较两个日期时间值?

我明白了这一点,所以回答了我自己的问题;我发现我遗漏了一条关键信息。我提到这个问题是在测试中出现的。我没有提到的是,我们正在插入记录,然后在单个事务和单个DbContext中测试所有记录

因为我对所有工作都使用相同的DbContext,所以为测试插入的警报对象被缓存。当我使用AsNoTracking查询对象时,DbContext必须在将对象返回给我之前刷新对象(因为它们的当前状态没有被跟踪,因此EF不知道),显然没有更新缓存中的内容(因为我们告诉EF我们不想跟踪对象)

在不进行AsNoTracking的情况下查询相同的对象会导致缓存命中;插入的对象仍在缓存中,因此将返回缓存的版本


有鉴于此,很明显为什么滴答声不匹配。非缓存对象从数据库中提取日期时间值,其中精度定义为仅存储最接近秒的时间。缓存对象具有原始的DateTime.Now值,该值将时间存储到毫秒。这解释了为什么两个DateTime之间的刻度不匹配,即使这两个对象表示相同的基础数据库记录。

我不确定,但您可以检查DateTime的精度。现在返回。它是否相当于
DATETIME
级别的精度?另外,请注意,
DATETIME2
中存储了更多的字节和数据,特别是为了更高的精度。因此,当您比较两种精度不同的数据类型时,您当然不会得到当前时间的相同值。谢谢@Radu的回复,但当我在问题中提到“DateTime”时,我指的是C#type。因为为SQL列定义的数据类型是datetime2(0),所以DateTime.Now的精度应该无关紧要。完全不考虑数据类型精度,如果EF6跟踪或不跟踪实体,为什么日期时间值不同?