【问题标题】:Query List of Dictionary<string, object>, can't cast from object to original typeDictionary<string, object> 的查询列表,不能从对象转换为原始类型
【发布时间】:2012-02-09 16:25:39
【问题描述】:

我在为以下数据创建 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 查询中构建我收到的操作(操作可以相等,更少,更大......)。 如果我构建表达式树,我仍然需要将数据转换为其原始类型吗?

谢谢!

【问题讨论】:

  • 我可以使用entityProps.Where(p =&gt; p[propName].ToString() == value.ToString());,但这仅适用于相等运算符。我想使用大于,小于..

标签: linq lambda runtime expression-trees


【解决方案1】:

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

    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));

【讨论】:

  • 这工作entityProps.Where(p =&gt; CompareToObject(value, p[propName], (x, y) =&gt; x == y));
【解决方案2】:

您可以尝试投射到int?:

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

【讨论】:

  • 直到运行时我才知道属性的类型。我需要这样的东西:entityProps.Where(p =&gt; (p[propName] as p[propName].GetType()) == value);
【解决方案3】:

您必须使用运算符将​​所有 ValueType 变量转换为对象:(object)

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

【讨论】:

  • 不,这不好。比较之类的操作无法按预期工作。
【解决方案4】:

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

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

完成。

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

更实用的方法是使用一些反射来执行此操作以调用适当的方法并从那里开始。

【讨论】:

  • 我收到错误:表达式树可能不包含动态操作 :(
  • 你已经展示了你的代码,其中entityProps 是一个列表。真的是这样还​​是另有原因。作为一个列表,它应该像我说的那样工作。
猜你喜欢
  • 1970-01-01
  • 2011-11-27
  • 2016-12-25
  • 2014-10-22
  • 1970-01-01
  • 2013-01-30
  • 2013-07-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多