Как я могу изменить запрос LinQ на лету? - PullRequest
0 голосов
/ 11 октября 2018

У меня в основном есть служба WebAPI, которая возвращает значения клиенту.

У меня есть контроллер для обработки documents запросов, которые можно параметризировать с помощью простого enum.

Это простое перечисление даетварианты выбора:

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

Я хотел бы изменить запрос LinQ "на лету", прежде чем запрос будет фактически обработан DBContext, избегая моего создания болезненного switch, который дублирует код, и это не такэтот простой для чтения, даже не элегантный.

Я на самом деле "справился" с проблемой, создав два разных метода в зависимости от того, задействован ли он Take(x) или DateTime .Where(), что делаетя немного нервничаю.

В этом методе я возвращаю 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;
}

Здесь я занимаюсь созданием DateTime дляwhere предложение:

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();
    }
}

Поскольку я всегда пытаюсь избегать использования сценариев с переключателем , я хотел бы изменить query на лету, избегая создания этогодва больших и некрасивых switch и мешающих мне параметризоватьсяИзвините сам запрос, вынуждая дублировать код.

Я попробовал LinqKit , но, честно говоря, я действительно не знаю, как применить мои потребности к нему.

Заранее спасибо и надеюсь, что примеры помогут.

1 Ответ

0 голосов
/ 11 октября 2018

я понимаю, что вы хотите изменить запрос на основе вашего перечисления.Я думаю, что это то, что вы хотите.

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);
  }
}
...