gpt4 book ai didi

sql-server-2008 - Entity Framework 和 DateTime 的毫秒精度比较

转载 作者:行者123 更新时间:2023-12-04 08:55:49 28 4
gpt4 key购买 nike

关于 DateTime 值的比较,我在 C# 下遇到了 Entity Framework (代码优先)的问题。我使用下面定义的类 Validity(为本示例进行了简化)作为其他实体的父类(super class),这些实体应及时具有定义的有效性。

public abstract partial class Validity {
[Key]
public int ID { get; set; }

public DateTime? ValidFrom { get; set; }
public DateTime? ValidTo { get; set; }

/**
* @brief This method builds an IQueryable from another IQueryable,
* with added restriction on ValidityFrom/To
*
* An object's validitiy is defined to
* 1. start at timestamp ValidFrom (=inclusive) and
* 2. to end before ValidTo (=exclusive).
* 3. If ValidFrom or ValidTo is NULL, it means to be "unbounded"
* in start or end time (respectively)
*
**/
public static IQueryable<T> isValidAt<T>(IQueryable<T> query, DateTime time) where T : Validity
{
return query.Where<T>(c =>
(!c.ValidFrom.HasValue || time >= c.ValidFrom) // If ValidFrom != NULL, the given timestamp must be equal or "after" ValidFrom
&& (!c.ValidTo.HasValue || time < c.ValidTo)); // If ValidTo != NULL, the given timestamp must be "before" ValidTo
}

/**
* @brief Shall invalidate the object at timestamp time (implicitly sets validTo attribute).
**/
public void inValidate(DateTime time)
{
ValidTo = time;
}
}

public class Item : Validity {
public string property { get; set; }
}

在最后三行,您将找到我们将作为示例的“Item”类。让我们看一下这个查询:
DateTime requestTime = DateTime.Now;
var items = from n in Validity.isValidAt(db.Items, requestTime)
select n;

此查询应仅返回在“requestTime”时“有效”的 Item 类的返回对象。请注意,对于 ValidTo == requestTime,项目将被视为“无效”(ValidFrom 到 ValidTo 的时间跨度是 -exclusive-ValidTo;请参阅上面源代码中的注释)。

问题

我实际上 - 拥有 - 结果集“项目”具有 ValidTo == requestTime .
我刚刚通过
Item i= items.FirstOrDefault();
if ((i.ValidFrom.HasValue && i.ValidFrom > requestTime)
|| (i.ValidTo.HasValue && requestTime >= i.ValidTo)) {

// ... SOME ERROR OUTPUT ...

}

** 注意:此错误不会很少发生,但几乎在软件中始终如 .inValidate(requestTime);通常调用来使对象无效。 **

我使用 LinQ 生成的 SQL 查询通过 Microsoft SQL Server Management Studio(Microsoft SQL Server 2008 用作后端)手动检查。我必须自己声明/设置@p__linq__0,@p__linq__1(两者都意味着requestTime)......
DECLARE @p__linq__0 DATETIME
DECLARE @p__linq__1 DATETIME
SET @p__linq__0 = '2012-10-23 15:15:11.473'
SET @p__linq__1 = '2012-10-23 15:15:11.473'

这实际上按预期工作。但是如果我使用 '2012-10-23 15:15:11' 作为值,我会收到错误的结果(如预期的那样)。它们与我的程序中的相似。所以我想这就是问题所在......

在数据库中,“DateTime”定义了毫秒,ValidFrom/ValidTo 被存储,包括毫秒。但我假设查询不包括时间戳的毫秒部分,出于任何原因......变量 requestTime 如何设置毫秒值。

不幸的是,我不知道如何检查查询中发送的实际值来验证这一点。我只知道如何使用 items.toString()-Method 来输出生成的 SQL,其中包含占位符。

我试过:
1. db.Log = Console.Out;由于没有定义“db.Log”的错误(自动完成也没有建议“Log”),它没有编译。而 db 是从 DbContext 派生的。
2. 也将“项目”转换为 ObjectQuery,然后使用 .ToTraceString() 不起作用,程序在运行时崩溃并显示转换无效的错误消息。

如果这很重要:我使用 .NET 4.0 和 EntityFramework.5.0.0。

问题
  • 如何记录/输出完整的 SQL(包括占位符的值)?
  • 如何以优雅的方式解决这个问题? ...我并不是说只是从 inValidate() 中分配给“ValidTo”的“时间”中减去一秒的黑客行为!

  • 最好的祝福,

    斯特凡

    编辑(发现更多细节)

    我通过 SQL 探查器检查了发生的情况,这似乎很好。查询时正确提供具有高(7 位)精度的时间戳。但是:我没有得到导致错误结果的 SELECT 。所以我猜测:它一定是一些缓存。所以我放了一个 db.SaveChanges();直接在我的 LINQ 查询之前。现在我在探查器中得到了所有查询。

    我尝试了以下代码来更改数据库中的数据类型。正如 Slauma 所建议的那样(见 https://stackoverflow.com/a/8044310/270591)。
    modelBuilder.Entity<Item>().Property(f => f.ValidFrom)
    .HasColumnType("datetime2").HasPrecision(3);
    modelBuilder.Entity<Item>().Property(f => f.ValidTo)
    .HasColumnType("datetime2").HasPrecision(3);

    我在重新启动之前删除了整个数据库......

    结果:使用 HasPrecision(x) 没有成功;其中 x 是 0、3 之一; (直接在前面有或没有 db.SaveChanges());但是:x = 7 与 db.SaveChanges() 相当有效;直接在查询之前...

    所以,不幸的是,这个问题仍然存在......

    当前的解决方法

    在将其分配给数据库对象属性之前,我将以下方法应用于任何 DateTime 值。它只是将 DateTime 舍入到整秒精度(我在数据库中配置)。这也适用于任何用于比较的 DateTime。

    结果:这更像是一个黑客而不是一个解决方案!我需要为所有的 setter 方法编写访问函数,这样直接赋值就不会意外发生。
        public static DateTime DateTimeDBRound(DateTime time) {
    DateTime t = time;
    long fraction = (t.Ticks % TimeSpan.TicksPerSecond);
    if (fraction >= TimeSpan.TicksPerSecond / 2)
    {
    t = t.AddTicks(TimeSpan.TicksPerSecond - fraction);
    }
    else
    {
    t = t.AddTicks(-fraction);
    }
    return t;
    }

    最佳答案

    问题 1 如何记录/输出完整的 SQL(包括占位符的值)?
    我认为最好的方法是使用 SQL Server 分析器。它显示所有语句和值。
    http://www.hibernatingrhinos.com/products/EFProf

    我知道没有其他方法可以提取执行的命令。

    关于sql-server-2008 - Entity Framework 和 DateTime 的毫秒精度比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13034266/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com