C# 使用字符串属性名创建where x=value lambda表达式
现在我正在做这样的事情:C# 使用字符串属性名创建where x=value lambda表达式,c#,.net,.net-core,C#,.net,.net Core,现在我正在做这样的事情: if (name == "Person") { query = query.Where(o => o.Person == val); } else if (name == "Location") { query = query.Where(o => o.Location == val); } else if (name == "Date") { query = query.W
if (name == "Person")
{
query = query.Where(o => o.Person == val);
}
else if (name == "Location")
{
query = query.Where(o => o.Location == val);
}
else if (name == "Date")
{
query = query.Where(o => o.Date == val);
}
...
query = WhereEquals(query, name, val);
我希望能够做到以下几点:
if (name == "Person")
{
query = query.Where(o => o.Person == val);
}
else if (name == "Location")
{
query = query.Where(o => o.Location == val);
}
else if (name == "Date")
{
query = query.Where(o => o.Date == val);
}
...
query = WhereEquals(query, name, val);
对于where方法,我没有答案。但是有一种扩展方法可以用来实现你的目标。此方法使用like函数,如果您想要精确匹配,只需删除即可 “%” 从搜索词中签名
public static IQueryable<T> Search<T>(this IQueryable<T> source, string propertyName, string searchTerm)
{
if (string.IsNullOrEmpty(propertyName) || string.IsNullOrEmpty(searchTerm))
{
return source;
}
var property = typeof(T).GetProperty(propertyName);
if (property is null)
{
return source;
}
searchTerm = "%" + searchTerm + "%";
var itemParameter = Parameter(typeof(T), "item");
var functions = Property(null, typeof(EF).GetProperty(nameof(EF.Functions)));
var like = typeof(DbFunctionsExtensions).GetMethod(nameof(DbFunctionsExtensions.Like), new Type[] { functions.Type, typeof(string), typeof(string) });
Expression expressionProperty = Property(itemParameter, property.Name);
if (property.PropertyType != typeof(string))
{
expressionProperty = Call(expressionProperty, typeof(object).GetMethod(nameof(object.ToString), new Type[0]));
}
var selector = Call(
null,
like,
functions,
expressionProperty,
Constant(searchTerm));
return source.Where(Lambda<Func<T, bool>>(selector, itemParameter));
}
公共静态IQueryable搜索(此IQueryable源、字符串属性名称、字符串搜索术语)
{
if(string.IsNullOrEmpty(propertyName)| | string.IsNullOrEmpty(searchTerm))
{
返回源;
}
var property=typeof(T).GetProperty(propertyName);
if(属性为空)
{
返回源;
}
searchTerm=“%”+searchTerm+“%”;
var itemParameter=参数(类型(T),“项目”);
var functions=Property(null,typeof(EF.GetProperty)(nameof(EF.functions));
var like=typeof(DbFunctionsExtensions).GetMethod(nameof(DbFunctionsExtensions.like),新类型[]{functions.Type,typeof(string),typeof(string)});
表达式expressionProperty=Property(itemParameter,Property.Name);
if(property.PropertyType!=typeof(字符串))
{
expressionProperty=Call(expressionProperty,typeof(object).GetMethod(nameof(object.ToString),新类型[0]);
}
变量选择器=调用(
无效的
喜欢
功能,
expressionProperty,
常数(搜索项);
返回source.Where(Lambda(选择器,itemParameter));
}
如果使用正确的类型传递值,则可以从您的exepmle执行此操作:
private Func<T, bool> WhereEquals<T>(string propertyName, object value)
{
return obj => typeof(T).GetProperty(propertyName)?.GetValue(obj)?.Equals(value) ?? false;
}
var activePeople = list.Where(WhereEquals<Person>("IsActive", true));
private Func WhereEquals(字符串属性名称,对象值)
{
返回obj=>typeof(T).GetProperty(propertyName)?.GetValue(obj)?.Equals(value)??false;
}
var activePeople=list.Where(WhereEquals(“IsActive”,true));
或:
private bool WhereEquals(T对象、字符串属性名称、对象值)
{
返回typeof(T).GetProperty(propertyName)?.GetValue(obj)?.Equals(value)??false;
}
var activePeople=list.Where(obj=>WhereEquals(obj,nameof(obj.IsActive),true));
如果我没有正确理解您的问题。Hi@buga,欢迎来到Stack Overflow。可能满足您的要求。如果您只有很少的修复属性,那么您的方法比反射要好得多@永顺:成本是多少(以美元和性能为单位)?如果我使用reflection@buga & & &