【问题标题】:How to dynamically add .Where() clause in LINQ如何在 LINQ 中动态添加 .Where() 子句
【发布时间】:2020-01-29 21:23:19
【问题描述】:

我有一个方法:
我在其中定义了一个表达式,仅当输入参数userType 具有值时才会在 linq 查询中。

public Institution GetInstitutionWithServices(int institutionId, UserTypes? userType)
{
  Expression<Func<Service, bool>> serviceUserTypeFilter = (s => true);

  if (userType.HasValue)
  {
    serviceUserTypeFilter = (s => s.UserType == userType.Value);
  };

  var query = _dbContext.Institution.Include(a => a.Services)
                                    .Where(a => a.Id == institutionId)
                                    .Select(m => new Institution
                                     {
                                       Id = m.Id,
                                       Name = m.Name
                                    .Where(x => x.Status == Service.ServiceStatus.Published) 
                                     //&& userType.HasValue ? x.UserType == userType.Value : false )
                                    .Where(serviceUserTypeFilter)
                                    .ToList()
                                    }).FirstOrDefault();
  return query;
}

我不知道如何为具有外键的其他表(数据库上下文)添加过滤器。
它有服务。
在评论了我需要调用 thorugh 表达式的部分,因为我得到了该代码的空引用异常
我得到的这段代码的错误是:

错误 CS1503
参数 2:无法从 'System.Linq.Expressions.Expression&lt;System.Func&lt;Test001.Domain.Service, bool&gt;&gt;' 转换为 'System.Func&lt;Test001.Domain.Service, bool&gt;'
Test001.Repositories

【问题讨论】:

  • 附带说明,您的var query 应命名为var result,因为它返回的是结果而不是查询本身。
  • 当然@GSerg ..我会编辑它。谢谢
  • 所以我需要用 Expression for SQL 包裹起来..
  • 我无法摆脱您的查询似乎很奇怪的感觉,您的 Institution 类成员 Name 正在使用 List 进行初始化,对吗?说说这行代码Name = m.Name.Where(x =&gt; x.Status == Service.ServiceStatus.Published).Where(serviceUserTypeFilter).ToList()

标签: c# linq


【解决方案1】:

在定义主查询后,没有什么能阻止您添加 .Where 子句:

 var query = _dbContext.Institution.Include(a => a.Services);
 if(something)
 {
    query = query.Where(a => a.Id == institutionId);
 }

 ...
 var results = query.ToList();  // <-- This 'executes' the query

 etc

在实际执行查询之前的任何时候(在您的情况下为 .ToList()),您都可以继续添加其他 linq 子句(.Where、.OrderBy 等)。

【讨论】:

  • 感谢@Neil,我不知道我可以像这样链接查询:)
  • 但我在查询中看不到我的选择
【解决方案2】:

您的代码似乎包含错误(什么是“..m.Name.Where(x => x.Status...”?),但我想您需要这样的解决方案:

Expression<Func<Service, bool>> servicesWhereClause;
        if (!userType.HasValue)
            servicesWhereClause = x => x.Status == Service.ServiceStatus.Published;
        else
            servicesWhereClause = x => x.Status == Service.ServiceStatus.Published
                && x.UserType == userType.Value;
        var result = _dbContext.Institution
            .Include(a => a.Services)
            .Where(a => a.Id == institutionId)
            .Select(i => new
            {
                Institution = i,
                Services = i.Services.Where(servicesWhereClause)
            })
            .ToList()
            .Select(anon => new Institution
            {
                Id = anon.Id,
                Name = anon.Name,
                // etc...
                Services = anon.Services
            })
            .ToList();

如果您想一次获得带有父记录的过滤子记录,您应该使用匿名返回类型并在此之后进行映射。遗憾的是,ef 不会跟踪此类记录。

【讨论】:

  • servicesWhereClause 期望 func 不是括号中的表达式。它不起作用,当我删除表达式包装时它会引发异常:Could not parse expression 'i.Services.Where(__servicesWhereClause_1)': The given arguments did not match the expected arguments: Object of type 'System.Linq.Expressions.TypedParameterExpression' cannot be converted to type 'System.Linq.Expressions.LambdaExpression'.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-09-15
  • 2012-12-28
  • 2010-10-21
  • 2010-11-03
  • 2010-10-25
  • 1970-01-01
  • 2023-03-29
相关资源
最近更新 更多