【问题标题】:DbFunctions TruncateTime return value [closed]DbFunctions TruncateTime 返回值
【发布时间】:2016-02-13 21:29:46
【问题描述】:

我的应用程序是 MVC 5、EF 6.1 和 SQL Server。 我正在使用

 public JsonResult GetUserDates()
        {
            var id= "1231231234";
            var data = db.Test.Where(x => x.Id == id).Select(c =>
            new
            {
                Date = DbFunctions.TruncateTime(c.Date)}).Distinct().ToList();
   return Json(data, JsonRequestBehavior.AllowGet);
        }

它返回正确的日期,但是在下拉列表中它看起来像这样:

2016-1-12 00:00:00:00000000

我怎样才能去掉多余的零。表中的数据类型为日期。

【问题讨论】:

  • How can I get rid of extra zeros 您的示例中有多少个额外的零? 2016-1-1**0** 00:00:00:00000000 呢?
  • 你在使用实体框架吗?
  • 是的,我使用的是 EF 6.1,我的问题中显示的额外零,它们看起来像时间!
  • 所以你只想要 Datetime 类的日期部分?问题变化......
  • 是的,我正在使用 SQL Server 并希望删除多余的零。 sql中的数据类型是日期。谢谢

标签: c# sql-server asp.net-mvc entity-framework


【解决方案1】:

CodeNotFound 的解决方案是可以接受的,但您也可以在 .NET 中而不是在 SQL 中构建字符串,如下所示:

public JsonResult GetUserDates()
{
    var id= "1231231234";
    var data = db.Test.Where(x => x.Id == id).Select(c => c.Date).Distinct()
                 .AsEnumerable()
                 .Select(x => new { 
                     Date = x.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture)
                 });

    return Json(data, JsonRequestBehavior.AllowGet);
}

.AsEnumerable() 之后的任何内容都将在查询结果从 SQL Server 返回到 .NET 后执行。这稍微好一些,因为数据将在底层 TDS 协议中以其本机二进制格式发送,而不是字符串。

不需要你最后的ToList

请注意,如果您的字段可以为空,因此您将对象声明为DateTime?,您将进行细微调整:

使用 C# 6 ?. 表示法:

Date = x?.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture)

或者如果你还在使用 C# 5,那么:

Date = x == null ? null : x.Value.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture)

此外,我将结果保存在您提供的相同结构中,但您可能会发现返回日期字符串数组而不是包含“日期”字段的对象数组更容易。需要考虑的事情。

我还要说这只是一个很好的解决方案,因为您提供了两个重要的细节:

  1. SQL 中的数据字段是date 类型。如果它实际上是一个datetimedatetime2smalldatetimedatetimeoffset,那么你会想要做一个范围查询而不是Distinct

    李>
  2. 结果将进入JsonResult,这通常会使用丑陋的"/Date(<ts>)/" 格式序列化DateTime,其中<ts> 是自1970-01-01T00:00:00Z 以来类似于unix 时间的毫秒数.但是,由于您使用的是日期而不是日期时间,因此使用这种格式可能会导致浏览器将日期解释为 UTC 午夜,并且对于某些时区可能会转移到午夜的另一边,从而导致在不同的日期。因此,发送 ISO-8601 格式的字符串 (yyyy-MM-dd) 是一种更好的方法。

【讨论】:

  • 谢谢马特,非常有帮助。但是我收到一个错误:CS1501 方法 'ToString' 没有重载需要 2 个参数,所以我使用 Date = x.Value.ToShortDateString() 我工作得很好。
  • 嗯.. 是right here。您不想要ToShortDateString,因为这将是特定于文化的,例如今天在美国是"2/13/2016" 或在世界其他地区是"13/2/2016"。对于 JSON,你真的应该坚持 ISO8601,"2016-02-13"
  • 你的Test.Date是定义为DateTime还是DateTime?
  • public Nullable 日期
  • 这与DateTime? 相同。我更新了答案以解决这个问题。
【解决方案2】:

TruncateTime 不会做你认为它会做的事。如果您的数据库中没有datetime 的时间部分,则截断时间不会执行任何操作。开始时没有时间,截断后也没有时间。

我认为您在这里缺少的是数据结构与其人类可读表示之间的区别。 TruncateTime 函数 DateTime 类型。此类型用于存储时间 日期。但是,您可以使用它来存储日期或时间。

您没有提供任何代码,除了这一行没有取得任何成果,并且您模糊地提到了一些“下拉列表”。因此,您很难回答您的问题。我还是会试试的。不过,对于未来,它有助于提供所有相关的代码,但不提供无关的代码,因为没有人喜欢滚动浏览代码页。

您很可能正试图在某种控制中使用数据库中的日期。而且您可能正在将控件数据绑定到结果集。这些是能够回答您的问题但您没有提供它们的关键信息。

许多控件将接受绑定到它们的任何对象,并将使用ToString 的(子)实现将对象转换为字符串以在控件中显示。默认情况下,DateTime.ToString 形成一个包含时间 日期的字符串。这可能就是您所看到的。

根据您的实现,您可能需要使用 ToString 的 this overload 将其显式转换为字符串。您将能够使用它指定输出字符串的精确格式,即您可以轻松地从输出中省略时间。

根据您的实现,您可能还需要在用户从您的控件中选择某些内容后进行从 stringDateTime 的反向转换,并且您希望将选择的结果传达回您在 @987654330 中的代码@ 格式。

阅读内容:字符串格式化、数据绑定、方法重载、继承、多态性。

【讨论】:

  • 感谢安德鲁花时间解释。你是对的,我应该解释得更多。我正在使用 Knockout Kendo 下拉列表。
【解决方案3】:

您正在使用 SQL 服务器,那么您可以使用 SqlFunctions 静态类。如果您不想要额外的零,您可以使用 SqlFunctions.DatePart

替换以下代码:

Date = DbFunctions.TruncateTime(c.Date)

使用此代码:

Date = SqlFunctions.DatePart("yyyy", c.Date) + "-" + SqlFunctions.DatePart("mm", c.Date) + "-" + SqlFunctions.DatePart("dd", c.Date)

【讨论】:

    猜你喜欢
    • 2020-03-14
    • 1970-01-01
    • 1970-01-01
    • 2011-02-24
    • 2020-02-02
    • 1970-01-01
    • 1970-01-01
    • 2022-01-27
    • 1970-01-01
    相关资源
    最近更新 更多