搜索所有字段

时间:2015-10-09 10:24:56

标签: c# entity-framework linq

我有一个实体,(defn - ([x] (. clojure.lang.Numbers (minus x))) ([x y] (. clojure.lang.Numbers (minus x y))) ([x y & more] (reduce1 - (- x y) more))) ,我希望用户能够搜索所有字段(理想情况下,所有字段,我只处理文本)。我怎么能这样做而不必明确地做

Device

这必须发生在数据库上,而不是在返回的对象中。

修改

我已经尝试了其中一条评论,其中一条没有用

devices.Where(d => 
    d.prop1.Contains(searchterm) || 
    d.prop2.Contains(searchterm))

错误是

  

无法创建类型的常量值   ' System.Reflection.PropertyInfo&#39 ;.只有原始类型或枚举   在这种情况下支持类型。

3 个答案:

答案 0 :(得分:1)

您可以根据实体的属性动态构建表达式,如下所示:

public IQueryable<T> CreateSearchQuery<T>(DbSet<T> db_set , string value) where T:class
{
    IQueryable<T> query = db_set;

    List<Expression> expressions = new List<Expression>();

    ParameterExpression parameter = Expression.Parameter(typeof (T), "p");

    MethodInfo contains_method = typeof(string).GetMethod("Contains", new[] { typeof(string) });

    foreach (PropertyInfo prop in typeof(T).GetProperties().Where(x => x.PropertyType == typeof (string)))
    {
        MemberExpression member_expression = Expression.PropertyOrField(parameter, prop.Name);

        ConstantExpression value_expression = Expression.Constant(value, typeof(string));

        MethodCallExpression contains_expression = Expression.Call(member_expression, contains_method, value_expression);

        expressions.Add(contains_expression);
    }

    if (expressions.Count == 0)
        return query;

    Expression or_expression = expressions[0];

    for (int i = 1; i < expressions.Count; i++)
    {
        or_expression = Expression.OrElse(or_expression, expressions[i]);
    }

    Expression<Func<T, bool>> expression = Expression.Lambda<Func<T, bool>>(
        or_expression, parameter);

    return query.Where(expression);
}

此方法包含DbSet和您要搜索的值。它循环遍历string类型的属性,并为每个属性创建一个&#34;包含&#34;表达式(例如p => p.Name.Contains("test"))。

然后它用OR表达式聚合表达式。

您可以像这样使用此方法:

var query = CreateSearchQuery(context.Devices, "name");

var result = query.ToList();

答案 1 :(得分:0)

您可以使用PropertyType和GetType()

devices.Where(prop =>
prop.PropertyType == query.GetType())

答案 2 :(得分:0)

查找Device类的所有属性。

context.Device.Where(device => properties.Any(prop => prop.GetValue(device, null) == query));

然后找到所有至少有一个属性值等于查询的设备。

if bmi < 18:
    text = 'Underweight'

elif bmi <= 24: # we already know that bmi is >=18 
    text = 'Ideal'

elif bmi <= 29:
    text = 'Overweight'

elif bmi <= 39:
    text = 'Obese'

else:
    text = 'Extremely Obese'