C# 为什么此查询解析为数据查询
我有一个linq to sql查询,它获取当前小时的所有日志(存储为Iqueryable): 然后我有另一个查询(也存储为Iqueryable),它获取当前正在处理的日志,并且不显示在该时间段的日志中C# 为什么此查询解析为数据查询,c#,linq,C#,Linq,我有一个linq to sql查询,它获取当前小时的所有日志(存储为Iqueryable): 然后我有另一个查询(也存储为Iqueryable),它获取当前正在处理的日志,并且不显示在该时间段的日志中 notDownloadedIds = (from x in cDataContext.CategoryCountryCategoryTypeMappings where !( from dll in c
notDownloadedIds = (from x in cDataContext.CategoryCountryCategoryTypeMappings
where !(
from dll in currentLogs
select dll.CategoryCountryCategoryTypeMappingID)
.Contains(x.CategoryCountryCategoryTypeMappingID)
select x);
当我调试并悬停在currentLogs上时,我看到一个sql查询,当我悬停在NotDownloadEdDS上时,我看到一个DataQuery。如果我重构NotDownloadEDID以不使用当前日志,NotDownloadEDID将保持为sql查询,而不是数据查询。为什么不下载EDID作为sql查询保留,和/或如何使其保持这种状态
如果我不这样做,当我在一个方法中使用它时,我会遇到问题
编辑使用sanders建议后,我发现生成的sql语句是
SELECT ccc.[CategoryCountryCategoryTypeMappingID], ccc.[CountryID], ccc.[CategoryID],
ccc.[CategoryTypeID], ccc.[URLSegment], ccc.[DTS], ccc.[DTSUTC]
FROM [Store].[CategoryCountryCategoryTypeMappings] AS ccc
WHERE EXISTS(
SELECT *
FROM [dbo].[DownloadLog] AS [t1]
WHERE ([t1].[CategoryCountryCategoryTypeMappingID]
<> ccc.[CategoryCountryCategoryTypeMappingID])
AND (DATEPART(Hour, [t1].[DTS])) = (DATEPART(Hour, GETDATE()))
)
选择ccc.[CategoryCountryCategoryTypeMappingID],ccc.[CountryID],ccc.[CategoryID],
ccc.[CategoryTypeID],ccc.[URLSegment],ccc.[DTS],ccc.[DTSUTC]
来自[Store]。[CategoryCountryCategoryTypeMappings]作为ccc
哪里有(
挑选*
从[dbo].[DownloadLog]到[t1]
其中([t1]。[CategoryCountryCategoryTypeMappingID]
ccc.[CategoryCountryCategoryTypeMappingID])
和(DATEPART(Hour,[t1].[DTS])=(DATEPART(Hour,GETDATE())
)
我需要改变存在的地方。。。。列,到不存在的位置。。。。。列=列。是否可以在不将其解析为数据查询的情况下执行此操作?我的猜测是,由于您正在将外部数据(
currentLogs
)合并为查询的一部分,Linq to SQL将从CategoryCountryCategoryTypeMappings
中提取所有数据,然后在Linq中对对象进行过滤
为什么这很重要?当然可能存在性能差异,但我希望您将查询公开为除
IEnumerable
或IQueryable
之外的任何查询,这取决于currentLogs
集合中对象的数量,您可以执行以下操作,这将导致SQL查询
我认为查询的最大参数计数(您的ID将被转换为)大约为2000
var ids = currentLogs
.Select(x => x.CategoryCountryCategoryTypeMappingID)
.ToList();
notDownloadedIds =
from x in cDataContext.CategoryCountryCategoryTypeMappings
where !ids.Contains(x.CategoryCountryCategoryTypeMappingID)
select x;
有一些微妙的问题会使您失去直接到SQL的映射。在不深入细节的情况下(我似乎记得
.Contains()
有问题),我建议您尝试将查询重构为不同的形式,例如:
notDownloadedIds = cDataContext.CategoryCountryCategoryTypeMappings.Where(mapping =>
!currentLogs.Select(dll => dll.CategoryCountryCategoryTypeMappingID)
.Any(id => id == mapping.CategoryCountryCategoryTypeMappingID))
如果我正确阅读了您的代码,这将产生一个等价的查询。这是否也转换为数据查询?问题是,稍后我必须将50k行与其他50k行进行比较,如果我不让sql server为我做这件事,速度会非常慢。2000部分很可能就是问题所在。我在和50kBy一起工作,天哪,这是可行的。它保持查询形式,但我认为我的结果不准确。我必须再看一点,看看是否需要重构。我在帖子中做了一个编辑,如果你能帮我,我将不胜感激。@Ukemi-我编辑了我的答案,以匹配你对这个问题的最新补充。看起来我在原始查询中错误地转换了某些内容。这是否改变了一个正确的工作方式?是的,如果可以的话,我会再次+1,但是之前的查询是什么
DataQuery
仍然是IQueryable
,因此您的LINQ查询应该生成大致相同的SQL查询。
notDownloadedIds = cDataContext.CategoryCountryCategoryTypeMappings.Where(mapping =>
!currentLogs.Select(dll => dll.CategoryCountryCategoryTypeMappingID)
.Any(id => id == mapping.CategoryCountryCategoryTypeMappingID))