结合LINQ查询

我正在为一组文件结果制作一个小查询。

public class f_results { public String name { get; set; } public DateTime cdate { get; set; } public DateTime mdate { get; set; } public DateTime adate { get; set; } public Int64 size { get; set; } } 

我有一个屏幕,用户可以在其上选择他们想要的内容。 目前我通过过滤系统:

  foundfiles = new BindingList(totalresults.Find(fname.Text,true)); if (fsize.Text.Trim() != "") { try { Int64 sz = Int64.Parse(fsize.Text); List y = (from p in foundfiles where p.size >= sz orderby p.size descending select p ).ToList(); foundfiles = new BindingList(y); } catch { } } if (adate.Text.Trim() != "") { try { List y; DateTime test = DateTime.Parse(adate.Text); if ((adateop.Text) == ">") { y = (from p in foundfiles where p.adate >= test select p).ToList(); } else y = (from p in foundfiles where p.adate <= test select p).ToList(); foundfiles = new BindingList(y); } catch { } } if (mdate.Text.Trim() != "") { try { List y; DateTime test = DateTime.Parse(mdate.Text); if ((mdateop.Text) == ">") { y = (from p in foundfiles where p.mdate >= test select p).ToList(); } else y = (from p in foundfiles where p.mdate <= test select p).ToList(); foundfiles = new BindingList(y); } catch { } } if (cdate.Text.Trim() != "") { try { List y; DateTime test = DateTime.Parse(cdate.Text); if ((cdateop.Text) == ">") { y = (from p in foundfiles where p.cdate >= test select p).ToList(); } else y = (from p in foundfiles where p.cdate <= test select p).ToList(); foundfiles = new BindingList(y); } catch { } } 

最后,我按照我想要的方式得到了我的结果,但是我想要处理大约72 TB的文件数据,所以我的列表中有大量文件和大量目录(totalresults是一个类型结果,其中包含文件列表(f_results)和目录(结果)..然后查找迭代并返回与给定正则表达式匹配的大量f_results列表。

有没有办法让我的LINQ查询一个查询? 鉴于并非所有选项都可以使用,例如他们可能只想要文件> x,或者因为..或..等而不使用。

我确实考虑过为测试制作标志,等等,因为它是最重要的测试部分..是更好的方式,还是更好? 或者在洗涤中无关紧要?

您可以事先生成filter,然后立即应用它们 – 您只需要迭代初始枚举一次,类似这样(缩短):

 IEnumerable foundfiles = new List(); var filters = new List>(); if (fsize.Text.Trim() != "") { long sz = long.Parse(fsize.Text); filters.Add(x => x.size >= sz); } if (adate.Text.Trim() != "") { DateTime test = DateTime.Parse(adate.Text); filters.Add(x => x.adate >= test); } foreach (var filter in filters) { var filterToApply = filter; foundfiles = foundfiles.Where(filterToApply); } finalResults = new BindingList(foundfiles); 

更重要的是,在处理完所有filter之前不要调用ToList() ,否则你会一遍又一遍地遍历完整的结果列表。

好的 – 我想半回答我自己的问题..

我可以结合到一个查询,以下工作得很好..理想吗? 可能不是!

我现在要看看BrokenGlass的建议,看起来很整洁!

  Boolean flag_size = false; Boolean flag_adate = false; Boolean flag_cdate = false; Boolean flag_mdate = false; Int64 sz=0; DateTime adatetest=DateTime.Now; DateTime cdatetest = DateTime.Now; DateTime mdatetest = DateTime.Now; String mop = mdateop.Text; String aop = adateop.Text; String cop = cdateop.Text; if (fsize.Text.Trim() != "") { try { sz = Int64.Parse(fsize.Text); flag_size = true; } catch { } } if (adate.Text.Trim() != "") { try { adatetest = DateTime.Parse(adate.Text); flag_adate = true; } catch { } } if (cdate.Text.Trim() != "") { try { cdatetest = DateTime.Parse(cdate.Text); flag_cdate = true; } catch { } } if (mdate.Text.Trim() != "") { try { mdatetest = DateTime.Parse(mdate.Text); flag_mdate = true; } catch { } } foundfiles = new BindingList(totalresults.Find(fname.Text, true)); List y = (from p in foundfiles.AsParallel() where (!flag_size || (flag_size && p.size >= sz)) && (!flag_mdate || (flag_mdate && mop == ">" && p.mdate >= mdatetest) || (flag_mdate && mop == "< " && p.mdate >= mdatetest)) && (!flag_adate || (flag_adate && aop == ">" && p.adate >= adatetest) || (flag_adate && aop == "< " && p.adate >= adatetest)) && (!flag_cdate || (flag_cdate && cop == ">" && p.cdate >= cdatetest) || (flag_cdate && cop == "< " && p.cdate >= cdatetest)) orderby p.size descending select p).ToList(); foundfiles = new BindingList(y); 

至少我建议删除.ToList()调用到处。 由于LINQ具有延迟调用,它将迭代一次,即使您有:

 var foundfiles = from p in foundfiles where p.size >= sz select p ; foundfiles = from p in foundfiles where p.mdate >= test select p 

更新 (在这种情况下,顺序by应该放在所有filter之后)

但如果你写:

 var foundfiles = (from p in foundfiles where p.size >= sz orderby p.size descending select p).ToList() ; foundfiles = (from p in foundfiles where p.mdate >= test select p).ToList(); 

它会迭代两次 – 这可能是一个严重的性能问题。

但是,如果您将此代码作为单个查询,我认为代码看起来不会简单得多。

另外,为什么要捕捉所有exception? 你不应该这样做。