C# LINQ到SQL特性
我在LINQtoSQL中遇到了一些特性 通过一个相对简单的查询,我想选择一些字段,但将日期字段格式化为字符串,这是我第一次实现的:C# LINQ到SQL特性,c#,linq,linq-to-sql,C#,Linq,Linq To Sql,我在LINQtoSQL中遇到了一些特性 通过一个相对简单的查询,我想选择一些字段,但将日期字段格式化为字符串,这是我第一次实现的: var list = dataContext.MyLists.Single(x => x.ID == myId); var items = from i in list.MyItems select new
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检查,它也可以正常工作,直到有空值
有什么想法吗
Anthony在第一个查询中,在第二行运行时,您已经从数据库中获得了数据(var items=…)。这意味着第二行在客户机上运行,ToSortDateString可以非常愉快地运行 在第二个查询中,由于select直接在IQueryable集合(dataContext.MyLists)上运行,因此它尝试将select转换为SQL以在服务器上处理,而ToSortDateString在服务器上不被理解-因此出现“无法转换…”异常 为了更好地理解这一点,您确实需要理解IQueryable和IEnumerable之间的区别,并且在这一点上Linq To Sql查询不再是IQueryable而变成IEnumerable。网上有很多关于这方面的东西 希望这有帮助
Paul我会在不进行格式化的情况下执行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() : ""
}
正如错误消息告诉您的,区别在于连接到SQL时可以在本地完成的操作与远程完成的操作 Linq代码必须由Linq转换为SQL,转换为用于远程数据拉取的SQL命令-任何必须在本地完成的操作都不能包含在内
一旦您将其拉入本地对象(在第一个示例中),它就不再使用LINQtoSQL,只使用普通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不支持
ToSortDateString()
,似乎您有两个完全不同的查询。一种是从MyList对象中的MyItems中进行选择。第二个是从MyList对象(而不是MyItems)中进行选择。两者的数据类型是否相同?在不知道表结构是什么的情况下调试它是非常困难的。很好。你是人类中的王者,我不知道一个可计算的东西能让我摆脱这种持续的痛苦,而我基本上尊重一个可计算的东西……天才。@DaveJellison:只要你意识到在asenemerable
之后进行的任何过滤等都会在过程中进行(而不是在数据库中)…@Jon,对吧,在我的例子中,这对于这种方法(小数据集)是很好的,在这种方法中,如果用户执行搜索或排序等操作,我最终会建立缓存,将所有内容都存储在内存中。虽然这可能看起来很愚蠢,但如果用户90%的时间没有搜索或排序,那么分页数据仍然是一个有价值的工具。Aka,不仅仅是执行.ToList()并将整个表预先存储在内存中。