gpt4 book ai didi

c# - 使用表达式的 LINQ 过滤器实现

转载 作者:太空狗 更新时间:2023-10-29 22:51:56 27 4
gpt4 key购买 nike

在 MVC4 中,我向用户提供搜索框来搜索表中的任何值。所以我在服务器端用 C# 实现通用过滤条件

需要帮助将多个表达式组合成单个表达式

 Expression<Func<T, bool>> 

例如

表格列

MenuText, Role Name (Role.Name mapping), ActionName

现在如果用户在搜索框中输入 ABC ,它可以在显示列的任何行中,则需要过滤。

模型

public class Menu
{
public string MenuText {get;set;}
public Role Role {get;set;}
public string ActionName {get;set;}
}

public class Role
{
public string Name {get;set;}
}

到目前为止我已经实现了

  /// <summary>
/// string[] properties property.Name (MenuText, ActionName), including deeper Mapping names such as (Role.Name)
/// </summary>
public static Expression<Func<T, bool>> FilterKey<T>(string filterText, params string[] properties)
{
ParameterExpression parameter = Expression.Parameter(typeof (T));
Expression[] propertyExpressions = properties.Select(
x => !string.IsNullOrEmpty(x) ? GetDeepPropertyExpression(parameter, x) : null).ToArray();

Expression<Func<T, bool>> predicate = PredicateBuilder.False<T>();
foreach (Expression expression in propertyExpressions)
{
var toLower = Expression.Call(expression, typeof(string).GetMethod("ToLower", System.Type.EmptyTypes));
var like = Expression.Call(toLower, typeof(string).GetMethod("Contains"), Expression.Constant(filterText.ToLower()));
//TODO: Combine expressions to form single Expression<Func<T, bool>> expression

}
return predicate;
}

/// <summary>
/// To Get Deeper Properties such as Role.Name Expressions
/// </summary>
private static Expression GetDeepPropertyExpression(Expression initialInstance, string property)
{
Expression result = null;
foreach (string propertyName in property.Split('.'))
{
Expression instance = result ?? initialInstance;
result = Expression.Property(instance, propertyName);
}
return result;
}

最佳答案

我已经创建了一些您应该能够使用的搜索IQueryable 扩展方法

完整的博文在这里:

http://jnye.co/Posts/6/c%23-generic-search-extension-method-for-iqueryable

GitHub 项目在这里(有一些额外的扩展用于 OR 搜索:

https://github.com/ninjanye/SearchExtensions

public static class QueryableExtensions  
{
public static IQueryable<T> Search<T>(this IQueryable<T> source, Expression<Func<T, string>> stringProperty, string searchTerm)
{
if (String.IsNullOrEmpty(searchTerm))
{
return source;
}

// The below represents the following lamda:
// source.Where(x => x.[property] != null
// && x.[property].Contains(searchTerm))

//Create expression to represent x.[property] != null
var isNotNullExpression = Expression.NotEqual(stringProperty.Body, Expression.Constant(null));

//Create expression to represent x.[property].Contains(searchTerm)
var searchTermExpression = Expression.Constant(searchTerm);
var checkContainsExpression = Expression.Call(stringProperty.Body, typeof(string).GetMethod("Contains"), searchTermExpression);

//Join not null and contains expressions
var notNullAndContainsExpression = Expression.AndAlso(isNotNullExpression, checkContainsExpression);

var methodCallExpression = Expression.Call(typeof(Queryable),
"Where",
new Type[] { source.ElementType },
source.Expression,
Expression.Lambda<Func<T, bool>>(notNullAndContainsExpression, stringProperty.Parameters));

return source.Provider.CreateQuery<T>(methodCallExpression);
}
}

这让你可以这样写:

string searchTerm = "test";  
var results = context.Menu.Search(menu => menu.MenuText, searchTerm).ToList();

//OR for Role name
string searchTerm = "test";
var results = context.Menu.Search(menu => menu.Role.Name, searchTerm).ToList();

您可能还会发现以下帖子很有用:

允许搜索跨多个属性的搜索扩展方法:

http://jnye.co/Posts/7/generic-iqueryable-or-search-on-multiple-properties-using-expression-trees

允许在属性上使用多个或搜索词的搜索扩展方法:

http://jnye.co/Posts/8/generic-iqueryable-or-search-for-multiple-search-terms-using-expression-trees

关于c# - 使用表达式的 LINQ 过滤器实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17855416/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com