我正在为一组文件结果制作一个小查询。
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<f_results>(totalresults.Find(fname.Text,true));
if (fsize.Text.Trim() != "")
{
try
{
Int64 sz = Int64.Parse(fsize.Text);
List<f_results> y = (from p in foundfiles where p.size >= sz orderby p.size descending select p ).ToList();
foundfiles = new BindingList<f_results>(y);
}
catch
{ }
}
if (adate.Text.Trim() != "")
{
try
{
List<f_results> 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<f_results>(y);
}
catch
{ }
}
if (mdate.Text.Trim() != "")
{
try
{
List<f_results> 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<f_results>(y);
}
catch
{ }
}
if (cdate.Text.Trim() != "")
{
try
{
List<f_results> 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<f_results>(y);
}
catch
{ }
}
最后,我按照我想要的方式得到了我的结果,但是我想要处理大约72 TB的文件数据,所以我的列表中有大量文件和大量目录(totalresults是一种类型结果,其中包含一个文件列表(f_results)和目录(结果)..然后查找迭代并返回一个与给定正则表达式匹配的大量f_results列表。
有没有办法让我的LINQ查询一个查询?鉴于并非所有选项都可以使用,例如他们可能只想要文件&gt; x,或者因为..或..等等而未使用
我确实考虑过为测试制作标志,等等,因为它是最重要的测试部分..是更好的方式,还是更好?或者在洗涤中无关紧要?
答案 0 :(得分:3)
您可以预先生成过滤器,然后立即应用它们 - 您只需要迭代一次初始枚举,类似这样(缩短):
IEnumerable<f_results> foundfiles = new List<f_results>();
var filters = new List<Func<f_results, bool>>();
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<f_results>(foundfiles);
更重要的是,在处理完所有过滤器之前不要再调用ToList()
,否则你会一遍又一遍地遍历完整的结果列表。
答案 1 :(得分:1)
至少我建议删除所有.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
更新(在这种情况下,应按所有过滤器后的顺序排列)
但如果你写:
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();
它会迭代两次 - 这可能是一个严重的性能问题。
但如果您将此代码作为单个查询,我认为代码看起来会更简单。
另外,为什么要捕捉所有异常?你不应该这样做。
答案 2 :(得分:1)
好的 - 我想半回答我自己的问题..
我可以结合到一个查询,以下工作得很好..理想吗?可能不是!
我现在要看看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<f_results>(totalresults.Find(fname.Text, true));
List<f_results> 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<f_results>(y);