我正在寻找一些搜索例程使用LINQ,并希望有一些动态where子句。因此,例如,如果用户想要按城市搜索或按州搜索,我会有一个动态LINQ Where<>调用而不是创建两个强类型LINQ表达式,然后根据用户想要搜索的方式使用适当的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在Visual Studio 2008示例中谈到了动态LINQ,我遇到了blog post。这似乎做我想要的,但我的问题是:
提前致谢!
答案 0 :(得分:9)
您可能需要查看PredicateBuilder
答案 1 :(得分:6)
这个功能真的很棒。 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,你甚至可以做多个吸气剂。
可以改进代码。我相信我添加了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 }
答案 2 :(得分:4)
它现在应该可用。我可以通过NuGet下载它:http://www.nuget.org/packages/System.Linq.Dynamic/
答案 3 :(得分:1)
我认为它不受微软“支持” - 它似乎是在公共许可下发布的,部分原因是:
(E)该软件按“原样”许可。 您自行承担使用的风险。该 贡献者没有表达 保证,担保或条件。 您可能有其他消费者 您当地法律规定的权利 此许可证无法更改。到了 在您当地允许的范围内 法律,贡献者排除了 对适销性的暗示保证, 适合特定目的和 非侵害。
关于第二个问题,我认为没有.NET 4版本。 3.5应该可以在4.0项目中正常工作,我认为没有太多可以添加的内容。据我所知,这是一个漂亮的小型库,用于执行偶尔的,基于字符串的一次性linq查询。也许您出于某种原因手动排序网格,并且需要根据表示相关属性的字符串修改集合排序顺序。瞧。我怀疑你会为此添加很多功能而付出很多努力。