动态 LINQ - 是否有 .NET 4 版本?

发布于 2024-10-20 00:23:44 字数 798 浏览 2 评论 0原文

我希望使用 LINQ 进行一些搜索例程,并希望有一些动态 where 子句。因此,例如,如果用户想要按城市搜索或按州搜索,我将有一个动态 LINQWhere<>调用,而不是创建两个强类型 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");

我遇到了 博客文章讨论了 Visual Studio 2008 示例中的动态 LINQ。这似乎符合我的要求,但我的问题是:

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

提前致谢!

I'm looking to use LINQ for some searching routines and wanted to have some dynamic where clauses. So, for example, if a user wants to search by city or search by state, I would have a dynamic LINQ Where<> call instead of creating two strongly typed LINQ expressions and then using the appropriate one based on how the user wants to search.

So I would like to do this:

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

instead of

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

or

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

I came across a blog post by Scott Guthrie talking about Dynamic LINQ in the Visual Studio 2008 samples. This seems to do what I want, but my questions are:

  1. Is this sample library supported by Microsoft?
  2. Scott Guthrie's article is in regards to VS2008 (.NET 3.5). Is there a better option for .NET 4? Maybe something that was released with .NET 4 that accomplishes the same thing (or something very close)?

Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

裸钻 2024-10-27 00:23:44

您可能想看看 PredicateBuilder

You may want to take a look at PredicateBuilder

梓梦 2024-10-27 00:23:44

如果有这个功能就太好了。 ADO.net Datatables 中也存在类似的功能。这对于 LinqToSql 也非常有帮助。当然,您会失去强类型检查,但这就是重点,您需要动态搜索。如果你正确处理异常,我真的认为这是一个值得拥有的功能。

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

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

我发现开发我需要的表达方式更好。 Ilya Builuk 的这篇文章演示了自定义表达式。 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 }

This feature would be really nice to have. A similar feature exists in ADO.net Datatables. It would be really helpful for LinqToSql as well. Sure you would lose strongly typed checking, but thats the whole point, you want dynamic searches. If you handle the exceptions properly I really think its a feature worth having.

You might consider adding a feature request to Microsoft Connect. The library already exists maybe they will consider adding official support for it. If you do make a feature request make sure you post a link here so we can vote for it. Microsoft Connect has voting system similar to stackoverflow. I have submitted a few myself LinqtoSql TableUpdate and VB.net Readonly Interfaces like C#.

I remember having some trouble with this library. I think it had something to do with static methods.

I found it better to develop the expressions I needed. This article by Ilya Builuk demonstrates custom expressions. The nice thing about Ilya's framework it removes a lot of the boilerplate code when doing operations like sorting for jqGrid.

I found it extremely helpful when learning about the underlying concepts of expressions.

The nice thing about this code is that it allows you to use dot operators for getters. Person.Age or if you want to violate Demeter you can even do multiple getters.

The code can be improved upon. I believe I added StartsWith and only allowed it for string operations as well as a few other search operations. Regardless its worth a look, it helped me understand linq expressions a lot.

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 enumerator:

public enum WhereOperation { Equal, NotEqual, Contains }
无人问我粥可暖 2024-10-27 00:23:44

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

It should now be available. I could download it through NuGet: http://www.nuget.org/packages/System.Linq.Dynamic/

不爱素颜 2024-10-27 00:23:44

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

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

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

I don't think it's "supported" by Microsoft - it seems to be released under a public license, which says in part:

(E) The software is licensed “as-is.”
You bear the risk of using it. The
contributors give no express
warranties, guarantees or conditions.
You may have additional consumer
rights under your local laws which
this license cannot change. To the
extent permitted under your local
laws, the contributors exclude the
implied warranties of merchantability,
fitness for a particular purpose and
non-infringement.

On your second question, I don't think there's a .NET 4 version. The 3.5 should work fine in a 4.0 project, and I don't think there's really much to add in. As I understand it, this was a nifty little library for doing those occasional, one-off string-based linq queries. Maybe you were for some reason manually sorting a grid, and needed to modify your collections sort order based on a string representing the property in question. Voila. I doubt you'll see a lot of effort put into adding a lot of features into this.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文