向嵌套的Linq选择添加where子句

3

我对Linq还不熟悉,如果您看到我真的不应该做的事情,请随时建议更改。

我正在开发一个新系统,允许警官注册加班。部分数据显示在地图上,并使用搜索条件过滤不需要的职位。为了使数据更易于处理,它被读入一个层次结构对象结构中,使用Linq。在这个例子中,一个工作可以包含多个班次,每个班次可以有多个可用职位。读取它们的Linq语句如下所示。

        var jobs = (from j in db.Job
                    join s in db.Shift on j.Id equals s.JobId into shifts
                    select new JobSearchResult
                    {
                        JobNumber = j.Id,
                        Name = j.JobName,
                        Latitude = j.LocationLatitude,
                        Longitude = j.LocationLongitude,
                        Address = j.AddressLine1,
                        Shifts = (from shift in shifts
                                  join p in db.Position on shift.Id equals p.ShiftId into positions
                                  select new ShiftSearchResult
                                  {
                                      Id = shift.Id,
                                      Title = shift.ShiftTitle,
                                      StartTime = shift.StartTime,
                                      EndTime = shift.EndTime,
                                      Positions = (from position in positions
                                                   select new PositionSearchResult
                                                   {
                                                       Id = position.Id,
                                                       Status = position.Status
                                                   }).ToList()
                                  }).ToList()
                    });

这段话的大意是:“那个方法可以正常运行并已经进行了测试。也许有更好的方法,如果你知道的话,可以自由发表建议。我的问题是:在查询创建之后,将会添加搜索条件。我知道我可以在创建查询时添加条件,但对于这个问题来说,在创建之后添加要更容易些。现在,我可以轻松地添加类似于以下内容的条件。”
jobs = jobs.Where(j => j.JobNumber == 1234);

然而,我遇到了如何处理班次或职位的困难。换句话说,我应该如何添加条件来表示班次在特定时间之后开始?以下是我想要实现但显然行不通的示例。
jobs = jobs.Shifts.Where(s = s.StartTime > JobSearch.StartTime)      //JobSearch.StartTime is a form variable.

有人有什么建议吗?

你是想根据班次筛选工作,还是想筛选每个工作下的班次数量? - Robin Day
它可以通过许多不同的标准进行过滤。例如:班次何时开始,班次持续多长时间,班次是否有空缺职位,工作地点在哪里,雇主是谁等等。因此,有很多不同的标准。是的,甚至可能有一个标准是一份工作有多少个班次。请记住,一份工作可以代表一个需要交通警察的教堂,也可以管理所有参加超级碗的警察。因此,对各种搜索标准的需求很高。 - Bomlin
1个回答

1

步骤1:创建关联以便你可以将连接隐藏在 EntitySet 属性后面。 http://msdn.microsoft.com/en-us/library/bb629295.aspx

步骤2:构建你的筛选器。你有3个可查询项和筛选器交互的可能性。首先指定最内层的筛选器,以便外部筛选器可以利用它们。

这里是所有的工作(未经过滤)。每个工作只有具有3个空闲职位的班次。每个班次都有这些空闲职位。

Expression<Func<Position, bool>> PositionFilterExpression =
  p => p.Status == "Open";

Expression<Func<Shift, bool>> ShiftFilterExpression =
  s => s.Positions.Where(PositionFilterExpression).Count == 3  

Expression<Func<Job, bool>> JobFilterExpression =
  j => true

步骤三:将所有内容组合在一起:

   List<JobSearchResult> jobs = db.Jobs
     .Where(JobFilterExpression)
     .Select(j => new JobSearchResult
     { 
       JobNumber = j.Id, 
       Name = j.JobName, 
       Latitude = j.LocationLatitude, 
       Longitude = j.LocationLongitude, 
       Address = j.AddressLine1, 
       Shifts = j.Shifts
         .Where(ShiftFilterExpression)
         .Select(s => new ShiftSearchResult
         {
           Id = s.Id,
           Title = s.ShiftTitle,
           StartTime = s.StartTime,
           EndTime = s.EndTime,
           Positions = s.Positions
             .Where(PositionFilterExpression)
             .Select(p => new PositionSearchResult
             {
               Id = position.Id,
               Status = position.Status
             })
             .ToList() 
         })
         .ToList()
     })
     .ToList(); 

我只是在尝试使用表达式方法,但一直试图在查询之后执行它。我认为这对我有用。我会尝试一下并让你知道结果。 - Bomlin
我对这个进行了一些尝试。它肯定是朝着正确的方向发展的。然而,我进行了一些检查,发现我的方法以及上面的方法都产生了大量的SQL流量,所以我要重新考虑我正在做的事情。感谢您提供的代码建议,我确实从中学到了一些东西,所以我会将其标记为解决方案。 - Bomlin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接