【问题标题】:OData - How to query DateTime greater or equal to given valueOData - 如何查询大于或等于给定值的 DateTime
【发布时间】:2020-08-02 12:44:05
【问题描述】:

我正在尝试在我的 OData 服务中查询日期时间大于或等于给定值的数据。它没有按预期工作

我已阅读文档:

https://docs.microsoft.com/en-us/odata/webapi/datetime-support#filter-datetime

程序集

  • Microsoft.AspNetCore.OData 7.4.0
  • NET Core 3
  • EF 核心

重现步骤

我尝试了以下查询格式:

  1. https://myurl/api/resource?$filter=city eq 'Kigali' and purchaseDateTime gt 2020-01-01T23:59:59.99Z &$orderby=purchaseDateTime desc HTTP 500 - 转换失败 从字符串转换日期和/或时间时。

  2. https://myurl/api/resource?$filter=city eq 'Kigali' and purchaseDateTime gt cast(2020-01-01T23:59:59.99Z,Edm.DateTimeOffset) &$orderby=purchaseDateTime desc 返回 HTTP 500 - 内部 服务器错误

  3. https://myurl/api/resource?$filter=city eq 'Kigali' and purchaseDateTime gt datetime'2020-01-01T23:59:59.99Z' &$orderby=purchaseDateTime desc

在 OData 网站上,这可行

https://services.odata.org/V4/OData/OData.svc/Products?$filter=ReleaseDate%20gt%202002-12-30T23:59:59.99Z

预期结果

按照http://services.odata.org响应的方式根据查询返回数据

实际结果

HTTP 错误请求或 HTTP 500

Microsoft says 这应该可以工作:

GET ~/Customers?$filter=Birthday lt cast(2015-04-01T04:11:31%2B08:00,Edm.DateTimeOffset)
GET ~/Customers?$filter=year(Birthday) eq 2010

我尝试过的其他信息来源:

  1. Filtering dates between x & y using ODATA
  2. ODATA DATE QUERY
  3. OData query filter for dateTime range

【问题讨论】:

  • 不要使用演员表。现在使用字符串 = DateTime.Now.ToString("yyyy-MM-ddThh:mm:ssZ");
  • 这不是 .NET,这是一个 OData 查询@jdweng​​span>
  • 你能提供你的模型吗?
  • 访问https://myurl/api/resource时可以获取数据吗?我测试了你的查询,它对我有用。
  • 您应该发布定义您正在查询的资源的 $metadata 部分,以及 `?$filter=city eq 'Kigali'&$top=2' 的结果,这应该提供

标签: c# datetime odata asp.net-core-webapi


【解决方案1】:

对于您的前两个查询,它适用于我。

 https://localhost:44339/odata/Patients?$filter=city eq 'Kigali' 
                                and purchaseDateTime gt 2020-01-01T23:59:59.99Z 
                                &$orderby=purchaseDateTime desc

 https://localhost:44339/odata/Patients?$filter=City eq 'Kigali' 
                                and PurchaseDateTime gt cast(2020-01-01T23:59:59.99Z,Edm.DateTimeOffset)
                                &$orderby=PurchaseDateTime desc

这里是model的代码。

public class Patient
{
    public ulong PatientId { get; set; }
    public string Name { get; set; }

    public string City { get; set; }

    public DateTime PurchaseDateTime { get; set; }

    public ICollection<PatientForms> PatientForms { get; set; }
}

【讨论】:

  • 谢谢 Michelle,我最终发现问题在于 EF Core 到 SQL 数据类型的转换...目标列是 datetime。发送的是datetime2,导致转换失败
【解决方案2】:

我找到了解决办法。

原来它与EF Core和我正在查询的列purchaseDateTime 的SQL数据类型有关

数据存储为 SQL 数据类型:datetime

在没有明确表示它应该映射到 SQL 数据类型 datetime 的情况下,EF Core 将其作为 SQL 数据类型 datetime2 发送

这是错误的来源:Conversion failed when converting date and/or time from character string

解决方案

模型应显式指定datetime 的列类型,使其如下所示

public class Patient
{
    public ulong PatientId { get; set; }
    public string Name { get; set; }

    public string City { get; set; }

    [Column(TypeName="datetime")] //overrides default of "datetime2"
    public DateTime PurchaseDateTime { get; set; }

    public ICollection<PatientForms> PatientForms { get; set; }
}

【讨论】:

  • 非常感谢您发布此信息!我在 DateTime 列中遇到了同样的错误。我们的大多数应用程序不使用 oData,我们通过流式 API 指定列类型,而不是像您在此处的解决方案那样的注释。但是 oData 不使用 fluent API,所以只有注释可以工作。我实际上是通过更改数据库中的数据类型来解决它的,但如果不是你的答案,我永远不会想到这一点
  • 很高兴它对你有用
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-02
  • 1970-01-01
  • 2016-09-30
  • 2020-05-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多