【问题标题】:Dynamic LINQ - Is There A .NET 4 Version?动态 LINQ - 是否有 .NET 4 版本?
【发布时间】:2011-07-06 23:54:18
【问题描述】:

我希望将 LINQ 用于一些搜索例程,并希望有一些动态的 where 子句。因此,例如,如果用户想要按城市搜索或按州搜索,我将使用动态 LINQ Where 调用,而不是创建两个强类型 LINQ 表达式,然后根据用户想要搜索的方式使用适当的表达式.

所以我想这样做:

String criteria="p.City='Pittsburgh'";  //or "p.State='PA'"
personData.Where(criteria)

而不是

personData.Where(p => p.City=="Pittsburgh");

或

personData.Where(p => p.State=="PA");

我遇到了 Scott Guthrie 的 blog post,他在谈论 Visual Studio 2008 示例中的动态 LINQ。这似乎符合我的要求,但我的问题是:

  1. Microsoft 是否支持此示例库?
  2. Scott Guthrie 的文章是关于 VS2008 (.NET 3.5)。 .NET 4 有更好的选择吗?也许与 .NET 4 一起发布的东西可以完成同样的事情(或非常接近的事情)?

提前致谢!

【问题讨论】:

  • 我可以看到直接的缺陷。您不会在编译时检查 LINQ 比较器。如果您看不出这为什么有用,请查看您的条件字符串...
  • @Sergio:这对于像 jqGrid 这样的搜索词作为字符串返回到控制器的东西很有帮助。很高兴有一个框架来处理它而不是一堆样板代码。
  • @David Hoerster:我记得这个库有一些问题。我发现开发我需要的表达方式会更好。本文演示了自定义表达式 (codeproject.com/KB/aspnet/AspNetMVCandJqGrid.aspx)。
  • @Sergio 我可能想让他有点聪明,但@snmcdonald 解释了一个适用于我情况的用途。我只是想了解所有选项。另外,看到关于它的 Guthrie 博客增加了我的兴趣,让我想知道这是否是一个可以使用的工具。谢谢!
  • 在rule.codeeffects.com/Linq-to-Sql-Entity-Data-Filter-Demo 上查看演示,它可以满足您的需求

标签: c# linq dynamic-linq linq-expressions


【解决方案1】:

你可能想看看PredicateBuilder

【讨论】:

  • 这是一段有趣的代码。我得去看看。谢谢!
  • 我刚刚测试过,它不区分大小写。干得好用户295190。
【解决方案2】:

这个功能真的很不错。 ADO.net 数据表 中存在类似的功能。这对 LinqToSql 也很有帮助。当然你会失去强类型检查,但这就是重点,你想要动态搜索。如果您正确处理异常,我真的认为它是一个值得拥有的功能。

您可以考虑向Microsoft Connect 添加功能请求。该库已经存在,也许他们会考虑为其添加官方支持。如果您确实提出了功能请求,请确保在此处发布链接,以便我们对其进行投票。 Microsoft Connect 具有类似于 stackoverflow 的投票系统。我自己提交了一些LinqtoSql TableUpdate 和VB.net Readonly Interfaces like C#。

我记得在使用这个库时遇到了一些问题。我认为这与静态方法有关。

我发现开发所需的表达方式会更好。 Ilya Builuk 的 article 演示了自定义表达式。 Ilya 框架的好处在于,它在为 jqGrid 进行排序等操作时删除了许多样板代码。

我发现它在学习表达式的基本概念时非常有用。

这段代码的好处是它允许您使用点运算符作为 getter。 Person.Age 或者如果你想违反 Demeter,你甚至可以做多个 getter。

代码可以改进。我相信我添加了StartsWith,并且只允许它用于字符串操作以及其他一些搜索操作。不管它是否值得一看,它帮助我理解了很多 linq 表达式。

public static IQueryable<T> Where<T>(this IQueryable<T> query, string column, object value, WhereOperation operation)
{
    if (string.IsNullOrEmpty(column))
        return query;

    ParameterExpression parameter = Expression.Parameter(query.ElementType, "p");

    MemberExpression memberAccess = null;
    foreach (var property in column.Split('.'))
        memberAccess = MemberExpression.Property
           (memberAccess ?? (parameter as Expression), property);

    //change param value type
    //necessary to getting bool from string
    ConstantExpression filter = Expression.Constant
        (
            Convert.ChangeType(value, memberAccess.Type)
        );

    //switch operation
    Expression condition = null;
    LambdaExpression lambda = null;
    switch (operation)
    {
        //equal ==
        case WhereOperation.Equal:
            condition = Expression.Equal(memberAccess, filter);
            lambda = Expression.Lambda(condition, parameter);
            break;
        //not equal !=
        case WhereOperation.NotEqual:
            condition = Expression.NotEqual(memberAccess, filter);
            lambda = Expression.Lambda(condition, parameter);
            break;
        //string.Contains()
        case WhereOperation.Contains:
            condition = Expression.Call(memberAccess,
                typeof(string).GetMethod("Contains"),
                Expression.Constant(value));
            lambda = Expression.Lambda(condition, parameter);
            break;
    }


    MethodCallExpression result = Expression.Call(
           typeof(Queryable), "Where",
           new[] { query.ElementType },
           query.Expression,
           lambda);

    return query.Provider.CreateQuery<T>(result);
}

WhereOperation 枚举器:

public enum WhereOperation { Equal, NotEqual, Contains }

【讨论】:

    【解决方案3】:

    现在应该可以使用了。我可以通过 NuGet 下载它:http://www.nuget.org/packages/System.Linq.Dynamic/

    【讨论】:

      【解决方案4】:

      我不认为微软“支持”它——它似乎是根据公共许可证发布的,其中部分内容是:

      (E) 软件按“原样”获得许可。 您自行承担使用的风险。这 贡献者没有明确表示 保证、保证或条件。 您可能有额外的消费者 您当地法律规定的权利 此许可证不能更改。到 在您当地允许的范围内 法律,贡献者排除 适销性的默示保证, 适合特定目的和 不侵权。

      关于第二个问题,我认为没有 .NET 4 版本。 3.5 应该可以在 4.0 项目中正常工作,而且我认为没有太多要添加的内容。据我了解,这是一个漂亮的小库,用于执行那些偶尔的、一次性的基于字符串的 linq 查询。也许您出于某种原因手动对网格进行排序,并且需要根据表示相关属性的字符串来修改集合排序顺序。瞧。我怀疑你会看到为此添加大量功能付出了很多努力。

      【讨论】:

      • 谢谢@Adam。我认为它不受支持 - 所以感谢您的澄清。你描述的如何使用它的方式就是我想如何使用它。
      • 是的,我也用过类似的方法。我认为这是它存在的主要原因。祝你好运!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-12
      • 2018-02-18
      • 2023-02-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多