在linq中使用循环

时间:2017-10-05 16:43:16

标签: c# entity-framework linq

关于我的业务的简短概述: 客户需要我们的定期服务,因此我们有一些保留服务已经保留了指定的持续时间。我们每天都应该根据轮次在start日期和end日期之间检索那些保留的服务。

为此,我需要这样:

1 using (MehrpouyanEntities dbContext = new MehrpouyanEntities())
2 {        
3     var query1 = dbContext.ReservedServices.Where(r => 
4                  DbFunctions.AddDays(r.LastServiceDate, r.Duration) >= start && 
5                  DbFunctions.AddDays(r.LastServiceDate, r.Duration) <= end);
6     var query2 = dbContext.ReservedServices.Where(r => 
7                  DbFunctions.AddDays(r.LastServiceDate, 2*r.Duration) >= start && 
8                  DbFunctions.AddDays(r.LastServiceDate, 2*r.Duration) <= end);
9      .
10     .
11     .
12      var queryN = dbContext.ReservedServices.Where(r => 
13                 DbFunctions.AddDays(r.LastServiceDate, N * r.Duration) >= start && 
14                 DbFunctions.AddDays(r.LastServiceDate, N * r.Duration) <= end);
15     // this means that the loop continues untill:
       // DbFunctions.AddDays(r.LastServiceDate, N * r.Duration) > end
16     return query1.Concat(query2). ... .Concat(queryN).ToList();
17 }

如何使用循环结构实现上述代码?

注1: N参数对于不同的r是不同的,我需要在查询中实现循环。

Note2 - 过分强调Note1: N作为循环的上限,根据每条记录r获取内部查询,因此每条记录{{1可能有不同的r。更准确地说,循环一直持续到N

Note3 - 示例:

DbFunctions.AddDays(r.LastServiceDate, N * r.Duration) > end

我想按如下方式检索3项服务:

  1. 2017年10月12日
  2. 2017年10月19日
  3. 2017年10月26日

3 个答案:

答案 0 :(得分:2)

棘手的问题。当然,LINQ to Entities查询无法解决。但可以通过混合LINQ to Entities / LINQ to Objects方法来解决。

让我们将问题分成两部分。

(1)检索所有具有

的服务记录
LastServiceDate + i * Duration >= start &&
LastServiceDate + i * Duration <= end

表示任何整数i,其中+表示添加天数。

让我们采取第一个条件

LastServiceDate + i * Duration >= start

因此对任何

都满意
i >= (start - LastServiceDate) / Duration

因此第一个服务日期是(考虑整数算术)

LastServiceDate + Duration * ceiling((start - LastServiceDate) / Duration)

(2)对于第一步检索的每项服务,生成startend之间的所有服务日期,并生成最终结果。

(1)可以使用LINQ to Entities(数据库)查询来实现,而(2)将使用LINQ to Objects在内存中完成。

以下是上述概念的实现:

var dbQuery = 
    from r in dbContext.ReservedServices
    where r.LastServiceDate <= start
    let firstDate = DbFunctions.AddDays(r.LastServiceDate, ((DbFunctions.DiffDays(r.LastServiceDate, start).Value + r.Duration - 1) / r.Duration) * r.Duration).Value
    where firstDate <= end
    select r;

var result = (
    from r in dbQuery.AsEnumerable()
    let firstDate = r.LastServiceDate.AddDays((((start - r.LastServiceDate).Days + r.Duration - 1) / r.Duration) * r.Duration)
    let count = 1 + (end - firstDate).Days / r.Duration
    from i in Enumerable.Range(0, count)
    select new { Service = r, Date = firstDate.AddDays(i * r.Duration) }
    ).ToList();

您可以将最终的匿名类型投影调整为符合您要求的任何内容。

答案 1 :(得分:0)

试试这个:

IEnumerable<ReservedService> myReservedServices;
var runningQuery = new List<ReservedService>();

var index = 1;
do{
    // query here, you need to set myReservedServices to a value
    // and check if it's non-empty to decide if you'd like to check the next day
    runningQuery.Add(query);

    // increment the index
    index++;
} while(myReservedServices != null && myReservedServices.Any());

答案 2 :(得分:0)

您可以循环遍历function addUser() { swal({ html: ` <div class="field"> Email: <p class="control has-icons-left"> <input class="input" type="email" placeholder="Email"> <span class="icon is-small is-left"> <i class="mdi mdi-email"></i> </span> </p> </div> <div class="field"> Name: <p class="control has-icons-left"> <input class="input" type="text" placeholder="Name"> <span class="icon is-small is-left"> <i class="mdi mdi-account"></i> </span> </p> </div> <div class="field"> Password: <p class="control has-icons-left"> <input class="input" type="text" placeholder="Password"> <span class="icon is-small is-left"> <i class="mdi mdi-key"></i> </span> </p> </div> <div class="field"> Level: <p class="control has-icons-left"> <input class="input" type="text" placeholder="Level"> <span class="icon is-small is-left"> <i class="mdi mdi-arrow-up"></i> </span> </p> </div> `, confirmButtonText: 'Confirm', cancelButtonText: 'Cancel', confirmButtonClass: 'button is-success has-right-spacing', cancelButtonClass: 'button is-danger', buttonsStyling: false, showCancelButton: true }) } ,直到您的查询返回任何内容

query