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检查它也可以正常工作,直到有空值。

有任何想法吗?

安东尼

我在没有进行格式化的情况下执行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() : "" } 

在第一个查询中,在第二行运行时(var items = …),您已经从数据库中获取了数据。 这意味着第二行在客户端运行,ToShortDateString可以非常愉快地运行。

在第二个查询中,因为select直接在IQueryable集合(dataContext.MyLists)上运行,它会尝试将select转换为SQL以便在服务器上进行处理,其中ToShortDateString不被理解 – 因此“无法转换…”exception。

要更好地理解这一点,您真的需要了解IQueryable和IEnumerable之间的区别,并且此时Linq To Sql查询将停止IQueryable并变为IEnumerable。 关于这一点,网上有很多东西。

希望这可以帮助,

保罗

就像错误消息告诉您的那样,差异是由于在连接到SQL时可以远程本地完成的操作。

Linq代码必须由Linq转换为SQL,用于远程数据提取的SQL命令 – 不能包含任何必须在本地完成的操作。

一旦你将它拉入本地对象(在第一个例子中),它就不再使用Linq to SQL了,只是普通的Linq。 那时你可以自由地对它进行局部操作。

也许有一个复制和粘贴错误或只是你的样本中的拼写错误。 但如果没有,这可能是问题……

在第二个查询中,您正在查询列表集合,而在第一个查询中,您正在查询列表中的项目。 但是您没有调整查询来解释这种差异。

你需要的可能是这个。 请注意第二个样本中没有出现的注释行。

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

Linq to SQL不支持ToShortDateString() http://msdn.microsoft.com/en-us/library/bb882657.aspx