【问题标题】:Dealing with DateTime using "Linq Methods"使用“Linq 方法”处理 DateTime
【发布时间】:2011-06-06 14:54:48
【问题描述】:

[ASP.NET 4.0 / EF 4.1]

嗨,

我正在尝试使用“Linq 方法”来根据日期时间字段过滤数据源,但出现错误:“仅支持原始类型('例如 Int32、String 和 Guid')上下文”。

我知道实体框架在处理日期时有一些限制,但我需要一些优雅的解决方案来处理这个问题。

我的代码是:

    public IList<Order> GetOrders(int? orderId = null, string customerId = null, int? employeeId = null, DateTime? orderDateFrom = null, DateTime? orderDateUntil=null, DateTime? requiredDate = null, DateTime? shippedDate = null)
    {
        IQueryable<Order> result;

        result = from order in ctx.Orders.Include("Order_Details")
                 select order;

        // Apply filters to the base query
        if (orderId != null)
            result = result.Where(o => o.OrderID.Equals(orderId));

        if (!String.IsNullOrEmpty(customerId))
            result = result.Where(o => o.CustomerID.ToUpper().Equals(customerId.ToUpper()));

        if (employeeId != null)
            result = result.Where(o => o.EmployeeID.Equals(employeeId));

        if (orderDateFrom != null)
            result = result.Where(o => o.OrderDate >= orderDateFrom);

        if (orderDateUntil != null)
            result = result.Where(o => o.OrderDate <= orderDateUntil);

        if (requiredDate != null)
            result = result.Where(o => o.RequiredDate == requiredDate);

        if (shippedDate != null)
            result = result.Where(o => o.ShippedDate == shippedDate);

        return result.ToList();
    }

当代码执行查询 (result.ToList()) 时,它会引发异常。如果我删除 datetime .Where 子句,它可以正常工作。

谢谢!

解决方案

我已将代码更改为:

    public IList<Order> GetOrders(int? orderId = null, string customerId = null, int? employeeId = null, DateTime? orderDateFrom = null, DateTime? orderDateUntil=null, DateTime? requiredDate = null, DateTime? shippedDate = null)
    {
        IQueryable<Order> result;

        result = from order in ctx.Orders.Include("Order_Details")
                 select order;

        // Apply filters to the base query
        if (orderId != null)
            result = result.Where(o => o.OrderID.Equals(orderId.Value));

        if (!String.IsNullOrEmpty(customerId))
            result = result.Where(o => o.CustomerID.ToUpper() == customerId.ToUpper());

        if (employeeId != null)
            result = result.Where(o => o.EmployeeID == employeeId.Value);

        if (orderDateFrom != null)
            result = result.Where(o => o.OrderDate >= orderDateFrom.Value);

        if (orderDateUntil != null)
            result = result.Where(o => o.OrderDate <= orderDateUntil.Value);

        if (requiredDate != null)
            result = result.Where(o => o.RequiredDate == requiredDate.Value);

        if (shippedDate != null)
            result = result.Where(o => o.ShippedDate == shippedDate.Value);

        return result.ToList();
    }

如果有人有更好的解决方案,请告诉我。

【问题讨论】:

  • 呵呵,一定是 4.1 的问题,因为 4.0 以这种方式支持日期;我们和你的一样有日期检查,它工作正常。你是先用代码吗?
  • 我不记得了,DateTime.Compare(t1, t2) 在 EF linq 查询中有效吗?
  • 在上面的代码中比较 DateTimes 也适用于 EF 4.1。真奇怪。你使用 SQL Server 吗?还是 SQL Server CE 版?还是其他数据库?

标签: c# asp.net entity-framework


【解决方案1】:

您正在使用可为空的类型 DateTime?在你的例子中。我不确定您的数据库列是否允许 NULL,但我会使用 date.Value 传递参数的值以确保 EF 不会超过它。请注意,对于可为空的类型,您还可以使用 HasValue 属性来检查您的参数是否包含正确的值。这导致:

if (orderDateFrom.HasValue)
   result = result.Where(o => o.OrderDate >= orderDateFrom.Value);

【讨论】:

  • 这看起来更干净,真的。但与可空类型的比较实际上也有效,在 LINQ to Entities 中也是如此。我刚刚测试了所有 4 种组合(OrderDateorderDateFrom 是否可以为空),它在我的示例中始终有效,我从未使用过 .Value
  • 谢谢@Bart。这真的是我的错,因为我不能使用像 result = result.Where(o => o.OrderID.Equals(orderId)) 这样的表达式。我必须使用表达式 result = result.Where(o=>Equals(orderId.Value))。据我了解,问题不仅与 DateTime(请参阅 OrderID)有关,还与与 referenceType 的比较有关。
  • @Slauma,你能提供一些代码摘录来证明你的肯定吗?谢了。
  • @rperson:我现在明白了,当我将Equals 与可空类型一起使用时,我确实也得到了您的例外。您确定这不是您的唯一问题吗?当您现在从 DateTime 过滤器中删除 .Value 时,您是否真的也遇到了异常? (我的示例实际上与您的 DateTime Where 子句之一完全一样,只是具有其他类和属性名称。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-09
  • 1970-01-01
相关资源
最近更新 更多