实体框架:使用已知名称的属性将过滤器应用于可查询

时间:2017-04-21 13:49:08

标签: c# entity-framework reflection

我想使用实体模型的属性来过滤结果;

这是我通常使用的代码:

db.Users.Where(ent => ent.Id > 5).ToList();

但我只能通过名称字符串(" Id")或其ProperyInfo访问该属性。

这是我尝试使用的,但它似乎无法运作:

db.Users.Where(ent => (int) ent.GetType().GetProperty("Id").GetValue(ent,null) > 5).ToList();

请注意,where子句可能会变得更复杂,我可能会使用另一种属性类型(而不是int)。

2 个答案:

答案 0 :(得分:1)

您可以做的一件事是使用属性名称构建Where表达式,例如:

public static Expression GreaterThanExpression<T>(string propertyName, object valueToCompare)
{
    var entityType = typeof(T);

    var parameter = Expression.Parameter(entityType, "entity");

    var lambda = Expression.Lambda(
            Expression.GreaterThan(
                Expression.Property(parameter, propertyName),
                Expression.Constant(valueToCompare)
            )
        , parameter);

    return lambda;
}

然后使用此静态方法,您可以在查询中执行以下操作:

var result=b.Users.Where(GreaterThanExpression("Id",5)).ToList();

如果您需要合并多个表达式,那么您应该看看这个post

答案 1 :(得分:0)

您可以使用反射和/或表达式构建器来动态创建LINQ查询,但这是一个很滑的斜率。

只需打开属性名称即可应用正确的过滤器。

假设您有string namestring value需要转换为LINQ查询的示例:

string name = "Id";
string value = "5";
switch (propertyName)
{
    case nameof(User.Id):
        var id = int.Parse(value);
        return db.Users.Where(ent => ent.Id > id).ToList();
    case nameof(User.Name):
        return db.Users.Where(ent => ent.Name == value).ToList();
}