2008-10-02 113 views
5

我遇到了一些LINQ to SQL的特性。LINQ to SQL的特性

有了一個相對簡單的查詢,我要選擇一些領域,但是格式化爲字符串的日期字段,這是我第一次像這樣實現的:

 var list = dataContext.MyLists.Single(x => x.ID == myId); 

     var items = from i in list.MyItems 
        select 
         new 
          { 
           i.ID, 
           i.Sector, 
           i.Description, 
           CompleteDate = i.CompleteDate.HasValue ? i.CompleteDate.Value.ToShortDateString() : "", 
           DueDate = i.DueDate.HasValue ? i.DueDate.Value.ToShortDateString() : "" 
          };        

後來我嘗試下面的查詢,這是完全一樣的,只是我從我的DataContext查詢直,而不是我的第一次查詢的元素:

 var items = from i in dataContext.MyLists 
        select 
         new 
          { 
           i.ID, 
           i.Sector, 
           i.Description, 
           CompleteDate = i.CompleteDate.HasValue ? i.CompleteDate.Value.ToShortDateString() : "", 
           DueDate = i.DueDate.HasValue ? i.DueDate.Value.ToShortDateString() : "" 
          }; 

第一個運行正常,但第二個查詢產生了:

無法將表達式'...'轉換爲SQL,無法將其視爲本地表達式。

如果我刪除格式日期的行,它工作正常。如果我刪除.HasValue檢查它也可以正常工作,直到有空值。

任何想法?

安東尼

+0

好像你有兩個完全不同的查詢。一種是從MyList對象中的MyItems中進行選擇。第二個是從MyList對象中選擇(不是MyItems)。兩者的數據類型是否相同?在不知道表結構是什麼的情況下調試它是相當困難的。 – Bryant 2008-10-02 16:06:48

回答

14

我會做的SQL部分沒有做的格式,然後做格式在客戶端:

var items = list.MyItems.Select(item => new { item.ID, item.Sector, item.Description, 
               item.CompleteDate, item.DueDate }) 
         .AsEnumerable() // Don't do the next bit in the DB 
         .Select(item => new { item.ID, item.Sector, item.Description, 
               CompleteDate = FormatDate(CompleteDate), 
               DueDate = FormatDate(DueDate) }); 


static string FormatDate(DateTime? date) 
{ 
    return date.HasValue ? date.Value.ToShortDateString() : "" 
} 
+0

Ooooh我喜歡.AsEnumerable()在那裏分裂。尼斯。 – Lucas 2008-10-07 22:54:20

8

在第一個查詢,您已經通過第二線運行(VAR項目= ...)時獲得了數據從數據庫返回的。這意味着第二行運行在客戶端,ToShortDateString可以非常愉快地運行。

在第二個查詢中,因爲select直接在IQueryable集合(dataContext.MyLists)上運行,所以它試圖將select轉換爲SQL以便在服務器上處理,其中ToShortDateString不被理解 - 因此「Could not Translate ..「例外。

爲了更好地理解這一點,您需要了解IQueryable和IEnumerable之間的區別,並且此時Linq To Sql查詢將停止成爲IQueryable並變爲IEnumerable。網上有很多關於此的東西。

希望這有助於

保羅

6

就像錯誤信息告訴你,不同之處在於連接到SQL時可以通過本地方式完成的任務。

Linq代碼必須由Linq轉換爲SQL轉換爲遠程數據的SQL命令 - 任何必須在本地完成的任務不能包含在內。

一旦你將它拉入本地對象(在第一個例子中),它不再使用Linq to SQL,只是簡單的Linq。那時你可以自由地對它進行本地操作。

2

也許在您的示例中存在複製和粘貼錯誤或者只是拼寫錯誤。但如果沒有,這可能是問題...

在第二個查詢中查詢列表集合,而在第一個查詢中查詢列表中的項目。但是您還沒有調整查詢來解決這種差異。

你需要的可能是這個。請注意沒有出現在第二個示例中的註釋行。

var items = from aList in dataContext.MyLists 
       from i in aList.MyItems // Access the items in a list 
       where aList.ID == myId // Use only the single desired list 
       select 
        new 
         { 
          i.ID, 
          i.Sector, 
          i.Description, 
          CompleteDate = i.CompleteDate.HasValue ? i.CompleteDate.Value.ToShortDateString() : "", 
          DueDate = i.DueDate.HasValue ? i.DueDate.Value.ToShortDateString() : "" 
         };