【问题标题】:Custom Linq method could not be translated无法翻译自定义 Linq 方法
【发布时间】:2021-12-23 09:33:12
【问题描述】:

我创建了一种自定义扩展方法来表示 SQL 'IN' 操作,我只是想让它可重用且更直接。

 public static bool In<T>(this T source, params T[] list)
        {
            return list.Contains(source);
        }

问题是我无法让它工作,这就是我所说的:

dataSource.Where(s => s.Id.In(6, 8)).Select(...);

这种方法虽然有效:

dataSource.Where(d => new int[] { 6, 8 }.Contains(d.Id)).Select(...)

我不断收到“无法翻译 LINQ .Where(b => b.Id\r\n .In(__n_0))' 表达式...”

【问题讨论】:

  • 如果没有LINQKit 或类似的注入表达式树的库,这是不可能的。如果你同意,我会发布解决方案。
  • 这是 EF Core 错误,而不是 LINQ 错误。 LINQ 不能自行查询任何内容。 EF Core 将 LINQ 查询转换为 SQL,并且无法转换不透明的函数调用。 IQueryable 运算符使用Expression&lt;Func&lt;,,&gt;&gt;,而不仅仅是Func&lt;..&gt; 参数
  • 您可以提前创建您需要的表达式,而无需添加任何额外的代码,但是......您希望从中获得什么?代码编写或参数化并不简单(ID 现在是硬编码的)。您正在尝试替换 .Where(s =&gt; ids.Contains(s.Id))
  • 知道了,谢谢。

标签: c# linq


【解决方案1】:

我曾经写过这个方法,使用表达式树, 基本上,你会这样做:

dataSource.In(s => s.Id, 6, 8).Select(...);

代码:

    public static IQueryable<TSource> In<TSource, TMember>(this IQueryable<TSource> source,
 Expression<Func<TSource, TMember>> identifier, params TMember[] values)
      {
          var parameter = Expression.Parameter(typeof(TSource), "m");
          var inExpression = GetExpression(parameter, identifier, values);
          var theExpression = Expression.Lambda<Func<TSource, bool>>(inExpression, parameter);
          return source.Where(theExpression);
      }

internal static Expression GetExpression<TSource, TMember>(ParameterExpression parameter, Expression<Func<TSource, TMember>> identifier, IEnumerable<TMember> values)
{
    var memberName = (identifier.Body as MemberExpression).Member.Name;
    var member = Expression.Property(parameter, memberName);
    var valuesConstant = Expression.Constant(values.ToList());
    MethodInfo method = typeof(List<TMember>).GetMethod("Contains");
    Expression call = Expression.Call(valuesConstant, method, member);
    return call;
}

可在 GitHubNuGet 以及其他 LINQ 扩展上使用:

【讨论】:

    猜你喜欢
    • 2022-10-20
    • 2021-10-24
    • 2021-06-23
    • 2020-10-26
    • 2022-01-19
    • 2021-12-28
    • 2020-03-11
    • 1970-01-01
    相关资源
    最近更新 更多