Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么此查询解析为数据查询_C#_Linq - Fatal编程技术网

C# 为什么此查询解析为数据查询

C# 为什么此查询解析为数据查询,c#,linq,C#,Linq,我有一个linq to sql查询,它获取当前小时的所有日志(存储为Iqueryable): 然后我有另一个查询(也存储为Iqueryable),它获取当前正在处理的日志,并且不显示在该时间段的日志中 notDownloadedIds = (from x in cDataContext.CategoryCountryCategoryTypeMappings where !( from dll in c

我有一个linq to sql查询,它获取当前小时的所有日志(存储为Iqueryable):

然后我有另一个查询(也存储为Iqueryable),它获取当前正在处理的日志,并且不显示在该时间段的日志中

  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))