首页 > 解决方案 > 可重用的 Linq 表达式(传递给项目不同部分的多个 .Where 子句)

问题描述

我有以下 linq 查询。

 var entities = await _context.Events
                .Include(x => x.Category)
                .Include(x => x.Owner)
                .Where(x =>
                    x.OwnerId == request.OwnerId && (
                        x.DateType == 1 && x.EndDateTimeUtc >= DateTime.UtcNow ||
                        x.DateType == 2 && x.Month >= DateTime.UtcNow.Month && x.Year >= DateTime.UtcNow.Year ||
                        x.Year >= DateTime.UtcNow.Year ||
                        x.DateType == 3 && x.Quarter >= quarter && x.Year >= DateTime.UtcNow.Year ||
                        x.Year >= DateTime.UtcNow.Year
                    ))
                .ToListAsync(cancellationToken);

我希望 .Where 子句中的表达式是一个函数/变量,我可以将它设置在其他地方,然后简单地将其传递给 where 子句。我有多个查询需要这些非常具体的条件,所以我想在一个地方创建它并传递它,而不必复制和过去。

我需要创建的函数需要接受 2 个参数(一个用于 request.OwnerId,一个用于 Quarter),其余的由日期/数据库字段生成

注意:部分查询基于特定字段,仅当 DateType 是特定数字 (1-3) 时才适用多个其他条件

标签: c#linq

解决方案


你可以像这样创建一个扩展方法IQueryable<Event>

public static class EventExtension
{
  public static IQueryable<Event> GetFiltered(this IQueryable<Event> query, Int32 ownerId, Int32 quarter)
  {
    return query.Where(x =>
      x.OwnerId == ownerId && (
        x.DateType == 1 && x.EndDateTimeUtc >= DateTime.UtcNow ||
        x.DateType == 2 && x.Month >= DateTime.UtcNow.Month && x.Year >= DateTime.UtcNow.Year ||
        x.Year >= DateTime.UtcNow.Year ||
        x.DateType == 3 && x.Quarter >= quarter && x.Year >= DateTime.UtcNow.Year ||
        x.Year >= DateTime.UtcNow.Year
      ));
  }
}

然后只需从任何地方调用它

var entities = await _context.Events
     .Include(x => x.Category)
     .Include(x => x.Owner)
     .GetFiltered(request.ownerId, request.quarter)

推荐阅读