2008-10-02 65 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() : "" 
         };