我在发这篇文章的时候,就有些犹豫:到底发不发在首页。linq的复杂查询是一个非常让人头痛的问题,我非常希望能够和园子里的高手交流下,怕发布在别的地方,这篇帖子很快就沉下去了,因此就放在首页吧,欢迎各位高手莅临指导。^_^
一、事件
最近做一项目,要求实现如下查询:
有三个表:论文(Paper),期刊(Magazine),期刊学科分类(MagazineSubjectClass),三者关系为:论文和期刊的关系为一对多(一篇论文对应一个期刊,一个期刊对应多篇论文),期刊和期刊分类的关系是一对多(一个期刊对应多个分类),如图:
要求实现的查询如下:
给出一“学科分类”集合(字符串数组),查询发表在“学科分类”属于这个集合中的杂志上的论文。
二、响应事件
我的思路如下:
- 根据学科分类找出符合条件的杂志
- 根据杂志找出符合条件的论文
于是,我写下如下linq语句:

Code
IQueryable<Magazine> magazines = database.Magazines.AsQueryable();
if (paperQueryInformation.MagazineQueryInformation.SubjectClass != null && paperQueryInformation.MagazineQueryInformation.SubjectClass.Length != 0)
{
magazines = database.MagazineSubjectClasses
.Where(q => paperQueryInformation.MagazineQueryInformation.SubjectClass.Contains(q.SubjectClass))
.Select(q => q.Magazine)
.Distinct();
query = query
.Where(q => magazines.Contains(q.Magazine));
}
运行,发生如下错如:
Queries with local collections are not supported
为什么出现这个错误呢?原来是linq的延迟执行导致了这个错误,知道了原因,我改进如下:

Code
IList<Magazine> magazines = database.Magazines.ToList();
if (paperQueryInformation.MagazineQueryInformation.SubjectClass != null && paperQueryInformation.MagazineQueryInformation.SubjectClass.Length != 0)
{
magazines = database.MagazineSubjectClasses
.Where(q => paperQueryInformation.MagazineQueryInformation.SubjectClass.Contains(q.SubjectClass))
.Select(q => q.Magazine)
.Distinct()
.ToList();
query = query
.Where(q => magazines.Contains(q.Magazine));
}
运行,就错误没有了,可是出现了新的错误,如下:
Method 'Boolean Contains(Srims.Business.Papers.Magazine)' has no supported translation to SQL
解决这个错误的方法就是将将类型转换为泛型 IEnumerable,使用 AsEnumerable<TSource> 可返回类型化为泛型 IEnumerable 的参数。LINQ to SQL(使用默认泛型 Query)会尝试将查询转换为 SQL 并在服务器上执行。但在有写情况下,此方法无法转换为 SQL。解决方法是用泛型 IEnumerable<T> 实现以替换泛型 IQueryable<T>。可通过调用 AsEnumerable<TSource>运算符来执行此操作。
我改进查询语句如下:

Code
IList<Magazine> magazines = database.Magazines.ToList();
if (paperQueryInformation.MagazineQueryInformation.SubjectClass != null && paperQueryInformation.MagazineQueryInformation.SubjectClass.Length != 0)
{
magazines = database.MagazineSubjectClasses
.Where(q => paperQueryInformation.MagazineQueryInformation.SubjectClass.Contains(q.SubjectClass))
.Select(q => q.Magazine)
.Distinct()
.ToList();
query = query
.Where(q => magazines.AsEnumerable()
.Contains(q.Magazine));
}
运行,结果正确,问题解决。
三、后记
经过不断的努力,问题终于解决了。在LINQ TO SQL的复杂查询中,linq的延迟执行和经linq语句翻译成sql语句的过程中,会发生很错想不到的错误,这是我碰到的最多的一个,今天终于解决了,拿出来和大家分享下,希望能抛砖引玉。^_^
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?