【问题标题】:Trying to use Dynamic LINQ but don't know where to start?尝试使用 Dynamic LINQ 但不知道从哪里开始?
【发布时间】:2023-03-10 05:52:01
【问题描述】:

我有一个 Blazor 应用程序,该应用程序显示一个事件日志,该应用程序还具有一个多选下拉菜单,该下拉菜单输出一个可拆分的字符串,用于过滤“SourceContext”类型。我想像下面那样动态构建“Where”子句,下面的代码显然不起作用,但代表了我想要实现的目标。 我已经尝试过 Predicates 并阅读了一些 Dynamic LINQ 站点来解决这个问题,此时我完全感到困惑。感谢您对此提供的任何帮助。

    string[] strAr = str.ToString().Split(",");
    string ctxFlt = string.Empty;
    for (int x = 1; x < strAr.Count(); x++)
    {
        if (x == 1)
        {
            ctxFlt += strAr[x].ToString();
        }
        else
        {
            ctxFlt += " and s.SourceContext ==  strAr[x].ToString();
        }
    }
    evLog = logdb.Logs.Where(s => s.SourceContext == $"{ctxFlt}").OrderByDescending(t => t.Timestamp).ToList();

【问题讨论】:

  • 本能地,我觉得您不需要 Dynamic Linq 或 Predicate Builder。似乎是Contains()Except() 的工作。请参阅here 获取一些线索。
  • 我完全同意你的看法。包含正是我想要使用的。问题是当我尝试将过滤器变量连接起来看起来像“a,b,c”时,我没有得到任何记录。如果我只使用一个变量,它就可以工作。 ctxFlt += strAr[x].ToString(); ... ...其中 e.SourceContext.Contains(ctxFlt) ...
  • 包含向后 - 尝试 Where(s => strArs.Contains(s.SourceContext))

标签: c# linq blazor


【解决方案1】:

同意罗伯特的观点,包含应该足够了,但您需要一个列表(枚举)而不是 .Contains 的数组。您的 Contains 实现是“String inside String”,即 foobar.Contains(foo) 不是 Linq Contains 以构建 SQL“WHERE field IN (x,y,z)”

var strAr = str.ToString().Split(",").ToArray().Distinct().ToList();
evLog = logdb.Logs.Where(s => strArs.Contains(s.SourceContext)).OrderByDescending(t => t.Timestamp).ToList();

但是,如果您想要一个完整的动态查询,您可以执行以下操作...

using System.Linq.Expressions;

            string[] strAr = str.ToString().Split(",");
            Expression conditions = Expression.Constant(false);
            var parameter = Expression.Parameter(typeof(Log), "log");

            for (int i = 0; i < strAr.Count(); i++)
            {
                Expression condition = Expression.Equal(
                        Expression.Property(parameter, "SourceContext"),
                        Expression.Constant(strAr[i])
                        );

                conditions = Expression.OrElse(conditions, condition);
            }

            var expression = Expression.Lambda<Func<Log, Boolean>>(conditions, parameter);

            var q = evLog = logdb.Logs.Where(expression).OrderByDescending(t => t.Timestamp).ToList();

【讨论】:

  • 是的,我把原来的“包含”倒过来了。我不知道必须先评估数组。上面的“包含”是有效的答案。谢谢罗伯特和迈克!
猜你喜欢
  • 1970-01-01
  • 2011-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-14
相关资源
最近更新 更多