字典<string,object =“”>的查询列表不能从对象转换为原始类型</string,>

时间:2012-02-09 16:25:39

标签: linq lambda runtime expression-trees

我需要帮助创建以下数据的linq查询:

List<Dictionary<string, object>> entityProps = new List<Dictionary<string, object>>();

        for (int i = 0; i < 10; i++)
        {
            entityProps.Add(new Dictionary<string, object>{
                {"prop1", Guid.NewGuid().ToString()},
                {"prop2","test"+i},
                {"prop3", i /0.5},
                {"prop4", i}
            });
        }

        string propName = "prop3"; // I can also get eny of prop 1-4
        int value = 65;            // here for prop2 I receive string e.g. "test3"
        entityProps.Where(p => p[propName] == value);

我收到以下错误:运算符'=='无法应用于'object'和'int'类型的操作数

我想将每个道具转换为它的类型,因为将来我想使用表达式树来为我接收的操作构建运行时lambda查询(操作可以相等,更少,更大......)。 如果我构建表达式树,我仍然需要将数据转换为其原始类型吗?

谢谢!

4 个答案:

答案 0 :(得分:0)

您可以尝试转换为int?

entityProps.Where(p => p[propName] as int? == value);

答案 1 :(得分:0)

您必须使用operator:(object)

将所有ValueType变量强制转换为object

但是,我认为你做错了。我会使用POCO类而不是字典。

答案 2 :(得分:0)

这里最简单的方法是使用dynamic。只需确保您必须进行的比较是有意义的。

var query = entityProps.Where(p => (dynamic)p[propName] == value);

完成。

生成执行此操作所需的表达式并不是一件容易的事。我确信已经有图书馆可以做到这一点,如果你不需要,不要重新发明轮子,特别是当你不知道如何制作它时。

更实际的方法是使用一些反射来调用适当的方法并从那里开始。

答案 3 :(得分:0)

您可以简单地编写一个辅助方法,以确保在执行谓词之前的值类型。类似的东西:

    public static bool CompareToObject<TSource>(TSource left, object right, Func<TSource, TSource, bool> predicate)
    {
        if (right is TSource)
            return predicate(left, (TSource)right);
        else
            return false;
    }

可以通过以下方式调用:

entityProps.Where(p => CompareToObject(p[propName], value, (x, y) => x == y));