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 & & &