2011-06-06 48 views
3

[ASP.NET 4.0/4.1 EF]使用 “Linq的方法” 与日期时间处理

嗨,

我正尝试使用 “Linq的方法” 的基础上日期时间字段来过滤数据源,但我收到错误:“在这种情况下只支持原始类型(如Int32,String和Guid)”。

我知道Entity Framework在处理日期时有一些限制,但我需要的是处理这个问题的一些优雅的解决方案。

我的代码是:

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(); 
    } 

如果有人有更好的解决方案,请让我知道。

+0

呵呵,必须是4.1的问题,因为4.0支持这种方式的日期;我们有和你一样的日期检查,它工作正常。你是先使用代码吗? – 2011-06-06 15:08:07

+0

我不记得,'DateTime.Compare(t1,t2)'在EF linq查询中工作吗? – FlyingStreudel 2011-06-06 15:10:10

+0

比较上面代码中的日期时间也适用于EF 4.1。真奇怪。你使用SQL Server吗?还是SQL Server CE版本?或者其他一些数据库? – Slauma 2011-06-06 15:13:21

回答

4

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

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

这看起来更干净,真实。但是,与可空类型的比较实际上也适用,在LINQ to Entities中也是如此。我只测试了所有4种组合('OrderDate'和'orderDateFrom'可为空或不可),它总是在我的例子中工作,我从来不必使用'.Value'。 – Slauma 2011-06-06 17:07:36

+0

谢谢@Bart。这真的是我的错,因为我不能使用像result = result.Where这样的表达式(o => o.OrderID.Equals(orderId))。我必须使用表达式result = result.Where(o => Equals(orderId.Value))。 因此,据我所知,这个问题不仅与DateTime(见OrderID)有关,而且与referenceType进行比较。 – outlookrperson 2011-06-06 17:16:00

+0

@Slauma,你能否提供一些代码摘录来证明你的肯定?韩国社交协会。 – outlookrperson 2011-06-06 17:41:25