【问题标题】:Operator >= cannot be applied to operands of type string and datetime运算符 >= 不能应用于字符串和日期时间类型的操作数
【发布时间】:2016-05-05 22:34:42
【问题描述】:

用户在url中输入两个参数,即开始日期和结束日期,它们以yyyyMMddhhmm的格式作为字符串输入。我正在尝试获取这些字符串并将它们转换为日期,以便查询我的数据库。

[ResponseType(typeof(Detail))]
public IHttpActionResult GetDetail(string StartDate, string EndDate)
{
    DateTime StartDateTime;
    DateTime EndDateTime;

    StartDateTime = new DateTime();
    EndDateTime = new DateTime();

    StartDateTime = DateTime.ParseExact(StartDate, "yyyyMMddhhmm", null);
    EndDateTime = DateTime.ParseExact(EndDate, "yyyyMMddhhmm", null);

    var detail = from a in db.Details where (a.callDate >= StartDateTime && a.callDate <= EndDateTime) select a;

    var Response = new DetailResponse() { status = true, calls = detail };
    return Ok(response);
}

但是我得到 >= 不能在日期时间和字符串中使用的错误。

编辑: 为了回答其中一个问题,我包括了一个用于显示数据的模型类。

DetailResponse.cs

public class DetailResponse
{
    public bool status { get; set; }
    public string statusMessage { get; set; }
    public IQueryable<Detail> calls { get; set; }
}

【问题讨论】:

  • a.callDate 是什么类型?
  • 啊,是我的sql数据库中的字符串。
  • 您可以在一个语句中声明和分配您的DateTimes:DateTime StartDateTime = DateTime.ParseExact(StartDate, "yyyyMMddhhmm", null);
  • 那你也应该把它解析为日期时间
  • 错误很明显——你不能比较两种不同的类型。我意识到现在已经有很多答案了,但你的问题到底是什么?

标签: c# linq datetime asp.net-web-api2


【解决方案1】:

这可能正在发生,因为callDate 是一个字符串。因此,您无法将字符串与日期时间进行比较。这个问题的解决方案是拥有相同的类型。话虽如此,我会将a.callDate 转换为DateTime

但是,我认为最好在数据库级别更改callDate 的数据类型。毫无疑问,这是个人意见。所以你不必遵循它。这样做您的代码将不需要任何更改。

现在,就代码而言,我上面建议的解决方案如下:

var allDetails = db.Details.AsEnumerable();
var details = from detail in details
              let callDate = DateTime.ParseExact(detail.callDate, "yyyyMMddhhmm", null)
              where callDate >= StartDateTime 
              && callDate <= EndDateTime
              select detail;

更新

正如我们在 cmets 中得出的结论,我们必须调用 AsEnumerable,才能使上述查询起作用。为什么需要这个?

借用乔恩·斯基特的话Reimplementing Linq to Objects: Part 36 – AsEnumerable

现在想要执行 在数据库中查询,然后在 .NET 中进行更多操作—— 特别是如果有些方面你基本上无法实现 LINQ to SQL(或您使用的任何提供程序)。例如,您可以 想要建立一个特定的内存表示,这不是真的 符合提供者的模型。

DateTime.ParseExact 无法在数据库方法中正确翻译。

【讨论】:

  • 好吧,我正在使用 api,他们希望将响应返回为字符串,但如果我想比较用户在 url 中键入的内容,我似乎需要将其作为日期时间。
  • 它似乎应该可以工作,但我收到了大量错误。 imgur.com/3lkLgXP
  • 嗯...我知道了...请尝试更新并告诉我。谢谢
  • 这实际上干扰了我的模型(我的错我从未发布过)。你建议我改变模型吗?我更新了我的问题以显示它。在实现您的答案时detail 有一个错误,它无法将 IEnumerable 转换为 IQueryable
  • 完全没有问题。是的,您还必须更改模型。 calls的类型应改为IEnumerable&lt;Detail&gt;
【解决方案2】:

您的比较失败,因为数据库中的日期是字符串类型,请尝试这样做:

[ResponseType(typeof(Detail))]
public IHttpActionResult GetDetail(string StartDate, string EndDate)
{
    DateTime StartDateTime = DateTime.ParseExact(StartDate, "yyyyMMddhhmm", null);
    DateTime EndDateTime = DateTime.ParseExact(EndDate, "yyyyMMddhhmm", null);

    var detail = from a in db.Details where (DateTime.ParseExact(a.callDate, "yyyyMMddhhmm", null) >= StartDateTime && 
                    DateTime.ParseExact(a.callDate, "yyyyMMddhhmm", null) <= EndDateTime) select a;
}

但是,您最好将callDate 的类型更改为日期而不是string

【讨论】:

    【解决方案3】:

    您的架构是什么样的? callDate 是一个字符串吗?您可能需要先将callDate 转换为DateTime,然后才能进行比较。

    var detail = from a in db.Details where (Convert.ToDateTime(a.callDate) >= StartDateTime &&  Convert.ToDateTime(a.callDate) <= EndDateTime) select a;
    

    【讨论】:

      【解决方案4】:

      正如已经说过的,您不能将字符串与 DateTime 进行比较,但是,因为日期格式是

      yyyyMMddhhmm

      (即年月日小时分钟),其中值都是数字并且从变化最小 -> 变化最大,您将可以安全地进行字符串比较:

      var detail = from a in db.Details where (a.callDate >= StartDate && a.callDate <= EndDate) select a;
      

      这是因为在比较字符串时“201601010101”小于“201612312359”(与“a”小于“b”的方式相同)。

      这将避免您将数据转换为DateTime

      话虽如此,通过进行转换,您正在验证数据,如果格式不正确,可能会显示错误。

      【讨论】:

        猜你喜欢
        • 2021-12-29
        • 2016-06-30
        • 2015-04-19
        • 1970-01-01
        • 2021-06-20
        • 1970-01-01
        • 2015-09-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多