结合LINQ查询

时间:2012-03-21 12:33:09

标签: c# 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<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,或者因为..或..等等而未使用

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

3 个答案:

答案 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);