我如何即时修改 LinQ 查询?

How could I modify a LinQ query on the fly?

我基本上有一个 WebAPI 服务,它 return 向客户端发送值。

我有一个控制器来处理 documents 请求,它可以通过一个简单的 enum.

参数化 提供

这个简单的枚举提供了这种选择:

public enum DataRange
{
    Last7Days,
    Last30Days,
    Last90Days,
    ThisYear,
    Last10,
    Last50,
    Last100,
    Last500,
    All
}

我想在 DBContext 实际处理查询之前修改 LinQ 查询 "on the fly",避免我创建一个痛苦的 switch,它会重复代码并且不那么容易阅读, 甚至不优雅。

我实际上 "handled" 创建两种不同方法的问题取决于它是 Take(x) 涉及还是 DateTime .Where() 过滤器,这让我感觉有点紧张。

在这种方法中,我 return lambda 基于它是一个 .Take(x) 涉及的查询:

private IQueryable<Documents> GetQueryByRegistries(DataRange dataRange)
{    
    switch (dataRange)
    {
        case DataRange.Last10:
            return Context.Documents
                              .Where(x => x.Auditoria)
                              .Include(x => x.Variables)
                              .Include(x => x.Events)
                              .OrderBy(x => x.Creation)
                              .Take(10);

        case DataRange.Last50:
            return Context.Documents
                              .Where(x => x.Auditoria)
                              .Include(x => x.Variables)
                              .Include(x => x.Events)
                              .OrderBy(x => x.Creation)
                              .Take(50);
                ...
        case DataRange.All:
            return Context.Documents
                              .Where(x.Auditoria)
                              .Include(x => x.Variables)
                              .Include(x => x.Events)
                              .OrderBy(x => x.Creation);

        default:
            return Context.Documents
                              .Where(x => x.Auditoria)
                            .Include(x => x.Variables)
                            .Include(x => x.Events)
                            .OrderBy(x => x.Creation);
    }
}


private IOrderedQueryable<Documents> GetQueryByDays(DataRange dataRange)
{
    var limitDateTime = DataRange.GetClause(dataRange);
    var documents = Context.Documents
                              .Where(x => x.Auditoria
                                  && x.Creation >= limitDateTime)
                                     .Include(x => x.Variables)
                                     .Include(x => x.Events)
                                     .OrderBy(x => x.Creation);
    return documents;
}

在这里,我为 where 子句处理 DateTime 的创建:

public static DateTime GetClause(DataRange dateTimeRange)
{
    switch (dateTimeRange)
    {
        case DataRange.Last7Days:
            return Last7Days();
        case DataRange.Last30Days:
            return Last30Days();
        case DataRange.Last90Days:
            return Last90Days();
        case DataRange.EsteAno:
            return ThisYear();
        default:
            return BigBang();
    }
}

因为我一直在尝试 avoid using switch 场景,所以我想即时修改 query,避免创建这两个又大又丑的 switches 并防止我参数化查询本身,强制重复代码。

我已经尝试 LinqKit 但老实说,我真的不知道如何将我的需求应用到其中。

在此先致谢,希望这些示例对您有所帮助。

据我了解,您想根据您的枚举更改查询。我想这就是你想要的。

private IQueryable<Documents> GetQueryByRegistries(DataRange dataRange)
{    
  // this is your base query. which will be common for all conditions.
  var query = Context.Documents
                          .Where(x => x.Auditoria)
                          .Include(x => x.Variables)
                          .Include(x => x.Events);

 switch (dataRange)
 {
    case DataRange.Last10:
        return query.Where(x => x.SomeId == 10).OrderBy(x => x.Creation)
                          .Take(10); // if you want to add Where again you can do that

    case DataRange.Last50:
        return query.OrderBy(x => x.Creation)
                          .Take(50);
            ...
    case DataRange.All:
        return query.OrderBy(x => x.Creation);

    default:
        return query.OrderBy(x => x.Creation);
  }
}