【问题标题】:Dynamic comparison with ef based on a property string name基于属性字符串名称与 ef 的动态比较
【发布时间】:2017-02-15 09:58:13
【问题描述】:

对于我的应用程序,我将一个“过滤器”对象传递给我的后端,该对象具有一个属性名称和一个属性值。

我在网上找到了下面的代码来做一个带有ef的动态包含

public static IOrderedQueryable<T> Contains<T>(this IQueryable<T> queryable, string propertyName, string propertyValue)
        {
            var parameterExp = Expression.Parameter(typeof(T), "type");
            var propertyExp = Expression.Property(parameterExp, propertyName);
            var method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
            var someValue = Expression.Constant(propertyValue, typeof(string));
            var containsMethodExp = Expression.Call(propertyExp, method, someValue);

            var expression = Expression.Lambda<Func<T, bool>>(containsMethodExp, parameterExp);

            var expcall = Expression.Call(typeof(Queryable), "Where", new[] {typeof(T)}, queryable.Expression,Expression.Quote(expression));

            return (IOrderedQueryable<T>)queryable.Provider.CreateQuery<T>(expcall);
        }

我这样称呼:

query = query.Contains(filter.Property, (string)filter.Value);

现在我正在尝试找到相同的比较来执行此操作:

query = query.Where(x => x.Status == filter.Value);

x.Status 是一个枚举所以

query = query.Where(x => x.Status.Equals(filter.Value));

抛出

无法创建“System.Object”类型的常量值。此上下文仅支持原始类型或枚举类型

即使我将其转换为 int。

所以我需要使用 '==' 而不是 equals,但我不知道如何构建像 Contains 这样的方法,而没有像 Contains 或 Equals 这样的方法名称

我想要什么,像这样:

query = query.IsTheSame(filter.Property, (Status)filter.Value);

【问题讨论】:

  • 请包含不工作的代码并解释你是如何知道它不工作的(编译器错误?运行时异常?错误结果?...?)

标签: c# .net entity-framework linq


【解决方案1】:

== 运算符检查完全匹配,如果您使用等效但不同的对象,它们之间的 == 运算符将为 false。 Equals 在相似但不同的对象的情况下为真。所以我想解决方案是

query = query.Where(x => (x.Status != null) && (x.Status.Equals(val)));

【讨论】:

    【解决方案2】:

    所以我需要使用 '==' 而不是 equals,但我不知道如何构建像 Contains 这样的方法,而没有像 Contains 或 Equals 这样的方法名称

    这实际上更容易感谢Expression.Equal 方法。

    这是一个示例实现(带有处理嵌套属性/字段的奖励):

    public static IQueryable<T> WhereEquals<T>(this IQueryable<T> source, string memberPath, object value)
    {
        var parameter = Expression.Parameter(typeof(T), "e");
        var member = memberPath.Split('.').Aggregate((Expression)parameter, Expression.PropertyOrField);
        var predicate = Expression.Lambda<Func<T, bool>>(
            Expression.Equal(member, Expression.Constant(value)),
            parameter);
        return source.Where(predicate);
    }
    

    你这样称呼:

    query = query.WhereEquals(filter.Property, filter.Value);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-01
      • 1970-01-01
      • 2020-02-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-15
      • 1970-01-01
      相关资源
      最近更新 更多