2011-06-06 71 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