Why does an IF Statement effect the outcome of my LINQ Statement?
最近,我在Linq工作了一段时间,在一些StackOverflowers的帮助下,我能够使这个语句正常工作:
1 2 3 4 5 6 7 8 9 10 | var traceJob = from jobDefinition in service.JobDefinitions where jobDefinition.Id == traceGuid select jobDefinition; if (traceJob != null && traceJob.Count() == 1) { traceJob.First().RunNow(); Console.WriteLine(traceJob.First().DisplayName +" Last Run Time:" + traceJob.First().LastRunTime); } |
然而,我很困惑,因为使它起作用的是
现在,据我所知,检查计数的
不,不应该。我猜你遇到了这样一种情况:枚举确实是空的,通过检查一个大于0的计数,
作为补充说明,这里的EDOCX1[1]可能是一个更好的检查,因为(取决于存储库的底层存储)它可能比EDOCX1[2]更快:
1 2 3 4 5 | if (traceJob != null && traceJob.Any()) { traceJob.First().RunNow(); Console.WriteLine(traceJob.First().DisplayName +" Last Run Time:" + traceJob.First().LastRunTime); } |
1 2 3 4 | var traceJob = (from jobDefinition in service.JobDefinitions where jobDefinition.Id == traceGuid select jobDefinition).SingleOrDefault(); |
可以使用single或default检查单个结果。它将返回与
这包括您的
MSDN文章
我认为您的问题是如何在调用LINQ语句时执行它们,而不是从它们被声明的地方执行。
所以你的声明:
1 2 3 4 | var traceJob = from jobDefinition in service.JobDefinitions where jobDefinition.Id == traceGuid select jobDefinition; |
这在功能上大致相当于:
1 2 3 4 5 6 | IEnumerable<JobDefinition> GetJobDefinitions(YourService service, Guid traceGuid) { foreach(var jobDefinition in service.JobDefinitions) if(jobDefinition.Id == traceGuid) yield return jobDefinition; } |
所以当你打电话给
如果可以反复调用
在任何情况下,最好只执行一次循环:
1 2 3 4 5 6 7 8 9 10 11 12 13 | var traceJobs = from jobDefinition in service.JobDefinitions where jobDefinition.Id == traceGuid select jobDefinition; // This is where the loop above actually executes - if it's empty it will return null var firstJob = traceJobs.FirstorDefault(); if(firstJob != null) { firstJob.RunNow(); Console.WriteLine(firstJob.DisplayName +" Last Run Time:" + firstJob.LastRunTime); } |
或者,可以通过将循环转换为列表或数组来强制执行该循环:
1 | var traceJobsExecuted = traceJobs.ToList(); |
关于https://stackoverflow.com/a/1745716/1289709我认为使用
Whenever you use SingleOrDefault, you clearly state that the query
should result in at most a single result. On the other hand, when
FirstOrDefault is used, the query can return any amount of results but
you state that you only want the first one.
所以把你的代码改成这样:
1 2 3 4 5 6 7 8 9 | var traceJob = (from jobDefinition in service.JobDefinitions where jobDefinition.Id == traceGuid select jobDefinition).FirstOrDefault(); if (traceJob != null) { traceJob.RunNow(); Console.WriteLine(traceJob.DisplayName +" Last Run Time:" + traceJob.LastRunTime); } |
我不知道您的"服务"的实际实现,但通常LINQ查询实际上只在被请求时填充其结果。因此count()确实更改了traceJob的状态,最可能的情况是填充内部集合。它看起来像first()没有填充内部集合,或者没有正确地执行它,即使通常它应该这样做。