过滤的麻烦

时间:2014-05-14 18:12:40

标签: c#

我的过滤器存在问题。我的目标是让加载的数据网格显示任何与创建的人,其中日期>今天 - 1个月。 我有一些过滤器surnameforename。我想显示在过去3个月内有一些活动的任何Person。那是通过这个查询找到的

(ctx.Interactions.Where(z => z.Attendees.Where(w => w.Person_Id == x.Id).Any() && z.ActivityDate >= recent  ).Any())

我遇到的问题是填写姓氏或姓氏时,我希望查询忽略创建的日期先决条件和交互先决条件。

Items.AddRange(ctx.People.
   Where(x => (
     ((Surname.Length == 0) && (Forename.Length == 0)) ? 
         (x.Created > limit)  : true  &&
         (((Surname.Length  == 0) || x.Surname.StartsWith(Surname)) &&  
         ((Forename.Length == 0) || x.Forename.StartsWith(Forename)) &&
         (ctx.Interactions.Where(z => z.Attendees.Where(w => w.Person_Id == x.Id).Any() && z.ActivityDate >= recent  ).Any())

我尝试过的一件事是移动交互查询并将其与x.created一起使用,但这会破坏运行时。目前它运行大约15秒,这个改变大约需要2分钟。任何提示或建议都会很棒。

recent是今天的日期 - 3个月

2 个答案:

答案 0 :(得分:0)

您可以拆分过滤表达式:

var filteredPeople = ctx.People; // here var should be replaced with IEnumerable<T> where T is the type of items in People
if (string.IsNullOrEmpty(Surname) && string.IsNullOrEmpty(Forename))
    filteredPeople = filteredPeople.Where(x => x.Created > limit);
else
{
    if (!string.IsNullOrEmpty(Surname))
        filteredPeople = filteredPeople.Where(x => x.Surname.StartsWith(Surname));
    if (!string.IsNullOrEmpty(Forename))
        filteredPeople = filteredPeople.Where(x => x.Forename.StartsWith(Forename));
    filteredPeople = filteredPeople.Where(x => ctx.Interactions.Where(z => z.ActivityDate >= recent)
                                                               .Any(z => z.Attendees.Any(w => w.Person_id == p.Id)));
}
Items.AddRange(filteredPeople);

答案 1 :(得分:0)

我认为您的问题可能在于使用条件运算符。条件运算符完全独立地使用?:子句 。所以你现在所说的是,

If Surname and Forename are length 0
  Then return ALL where x.Created > limit
Else
  Then apply all other filters.

我稍微重写了一下这个问题。这应该可以提高性能,因为它将检索更少(更准确)的结果。

Items.AddRange(ctx.People.
   Where(x => (
        ((Surname.Length == 0 && Forename.Length == 0) ? x.Created > limit  : true)  
        &&
         (
            (Surname.Length  == 0 || x.Surname.StartsWith(Surname))
            && (Forename.Length == 0 || x.Forename.StartsWith(Forename)) 
            && (ctx.Interactions.Any(z => z.Attendees.Any(w => w.Person_Id == x.Id) && z.ActivityDate >= recent))
         )

这是另一个没有两次点击ctx的版本,而是从Person&gt;遍历的版本。 Attendee&gt; Interaction而非倒退。这也可能会影响性能:

Items.AddRange(ctx.People.
   Where(x => (
        ((Surname.Length == 0 && Forename.Length == 0) ? x.Created > limit  : true)  
        &&
         (
            (Surname.Length  == 0 || x.Surname.StartsWith(Surname))
            && (Forename.Length == 0 || x.Forename.StartsWith(Forename)) 
            && x.Attendees.Any(attendee => attendee.Interactions.Any(interaction => interaction.ActivityDate >= recent))
         )