【问题标题】:Using an expression with multiple parameters in a linq statement在 linq 语句中使用具有多个参数的表达式
【发布时间】:2021-08-23 18:14:27
【问题描述】:

好的,所以我正在尝试编写一些 Blazor 代码,它允许我传入一个表达式,然后在通用(模板)类中使用该表达式。我不确定我的问题是与 blazor 相关还是只是我缺乏表达知识。

这是我的表达式,它与其余代码位于一个单独的文件中。 u(用户)要搜索的实体,s(字符串)搜索文本。

private Expression<Func<User,string, bool>> SearchExpression => (u,s) => string.IsNullOrWhiteSpace(s)
         || ((u.Email.Contains(s)) || (u.UserName.Contains(s)));

这里是我想使用表达式的地方。

private async Task GetItems()
{
    items = await context
        .Set<TItem>()
        .Where(q => SearchExpression)
        .Skip((currentPage - 1) * pageSize).Take(pageSize)
        .ToListAsync();
}

所以被搜索的实体是TItem 类型(在这种情况下是用户),但是我需要包含searchText,但我一辈子都无法弄清楚如何。最初我有searchText作为参数的表达式,但我也不知道如何调用它。

【问题讨论】:

  • 如果s 为空,则根本没有理由添加Where 子句。至于使用一个或多个参数 - Where (q=&gt;SearchExpression(q,value)).
  • s 不为空,我只是没有将它包含在我的示例代码中,因为我找不到任何编译方法。当我按照您的建议尝试这样做时,我得到“不可调用的成员'...SearchExpression'不能像方法一样使用”
  • 考虑使用 Dynamic Linq - System.Linq.Dynamic.Core

标签: c# linq lambda blazor


【解决方案1】:

我建议在这里使用LINQKit。它只需要配置 DbContextOptions:

builder
    .UseSqlServer(connectionString)
    .WithExpressionExpanding(); // enabling LINQKit extension

然后你可以通过Invoke扩展使用你的表达式:

private async Task GetItems()
{
    items = await context
        .Set<TItem>()
        .Where(q => SearchExpression.Invoke(q, str))
        .Skip((currentPage - 1) * pageSize).Take(pageSize)
        .ToListAsync();
}

您的SearchExpression 将被注入到 ExpressionTree 中,并且应该生成正确的 SQL。

【讨论】:

  • 我之前尝试过 linq kit,但不知道需要将 .WithExpressionExpanding() 添加到构建器。非常感谢
  • 它是新的。最新版本有这个功能。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-02-02
  • 2018-04-30
  • 1970-01-01
  • 2012-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多