LINQ to SQL特性

时间:2020-03-06 15:02:07  来源:igfitidea点击:

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

有任何想法吗?

安东尼

解决方案

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

在第二个查询中,由于选择直接在IQueryable集合(dataContext.MyLists)上运行,因此它将尝试将选择转换为SQL以在服务器上进行处理,在该服务器上无法理解ToShortDateString,因此出现"无法翻译.."异常。

为了更好地理解这一点,我们确实需要了解IQueryable和IEnumerable之间的区别,并且此时Linq To Sql查询不再是IQueryable而是变为IEnumerable。网络上有很多与此有关的东西。

希望这可以帮助,

保罗

我会不做格式化就做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命令,因为远程数据无法提取必须在本地完成的所有操作。

一旦将其拉入本地对象(在第一个示例中),它就不再使用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