【问题标题】:Dynamic + linq compilation error动态 + linq 编译错误
【发布时间】:2011-03-27 13:33:36
【问题描述】:

我会提前说,我正在用 linq 对动态数据做一些非常可怕的事情。 但我不知道为什么这个查询无法编译:

错误 1 ​​属性 'h__TransparentIdentifier0' 不能与类型参数一起使用

公开课程序 { 公共静态无效主要(字符串[]参数) { var docs = 新动态[0]; var q = 来自文档中的文档 其中 doc["@metadata"]["Raven-Entity-Name"] == "案例" 其中 doc.AssociatedEntities != null 来自 doc.AssociatedEntities 中的实体 where entity.Tags != null // 此处的编译器错误 来自 entity.Tags 中的标签 其中 tag.ReferencedAggregate != null 选择新的 {tag.ReferencedAggregate.Id, doc.__document_id}; } } 公共静态类 LinqOnDynamic { 私有静态 IEnumerable 选择(此对象自身) { 如果(自我 == 空) 产量中断; if (self is IEnumerable == false || self 是字符串) throw new InvalidOperationException("试图枚举" + self.GetType().Name); foreach (var item in ((IEnumerable) self)) { 收益退货项目; } } public static IEnumerable SelectMany(这个对象源, Func> collectionSelector, Func 结果选择器) { return Enumerable.SelectMany(Select(source), collectionSelector, resultSelector); } public static IEnumerable SelectMany(这个对象源, Func> collectionSelector, Func 结果选择器) { return Enumerable.SelectMany(Select(source), collectionSelector, resultSelector); } public static IEnumerable SelectMany(这个对象源, Func> 选择器) { 返回 Select(source).SelectMany(selector); } public static IEnumerable SelectMany(这个对象源, Func> 选择器) { 返回 Select(source).SelectMany(selector); } }

为了雪上加霜,以下工作:

var docs = 新动态[0]; var q = 来自文档中的文档 其中 doc["@metadata"]["Raven-Entity-Name"] == "案例" 其中 doc.AssociatedEntities != null 来自 doc.AssociatedEntities 中的实体 其中 entity.Tags != null 来自 entity.Tags 中的标签 选择新的 { tag.ReferencedAggregate.Id, doc.__document_id };

只有当我添加时:

其中 tag.ReferencedAggregate != null

我在前两行得到一个错误:

其中 entity.Tags != null // 此处出现编译器错误

不知道发生了什么

【问题讨论】:

    标签: c# linq dynamic


    【解决方案1】:

    如果我尝试将您的电话转换为:

    var q = from doc in docs.Where(doc => doc["@metadata"]["Raven-Entity-Name"] == "Cases" || doc.AssociatedEntities != null)
            from entity in doc.AssociatedEntities.Where(entity => entity.Tags != null)
    

    我得到一个不同的编译器错误,它可能揭示了正在发生的事情:

    '不能将 lambda 表达式用作动态调度操作的参数,除非先将其转换为委托或表达式树类型'

    所以我猜你必须重载 Where 运算符。

    【讨论】:

    • 谢谢,就是这样。我通过使用以下方法结束了这个问题: from tag in entity.Tags.Where((Func)(t => t.ReferencedAggregate != null)) 丑得要命。我尝试在那里编写扩展方法,但我不知道如何让 CSC 接受它。
    【解决方案2】:
    var q = 来自文档中的文档 其中 doc["@metadata"]["Raven-Entity-Name"] == "案例" 其中 doc.AssociatedEntities != null 来自实体 ((IEnumerable)doc.AssociatedEntities) .Where(entity => entity.Tags != null) 从标记输入 ((IEnumerable)entity.Tags) .Where(tag => tag.ReferencedAggregate != null) 选择新的 { tag.ReferencedAggregate.Id, doc.__document_id };

    这样好一点。不完美,但它就像开始一样——在你迷失方向之前,你只能深入这么多关卡。

    【讨论】:

      【解决方案3】:

      匿名类型返回是 h__TransparentIdentifier0 并由编译器在编译时处理 - 问题出现在“动态优先顺序” - 在这里阅读: Method-missing difficulties in C# 4.0: dynamic vs RealProxy

      我今天刚刚处理了最近的一篇文章。我有一个小小的猜测,并说 Anonymous 类型是在动态分配之后准备的 :) - 编译器知道这一点并且正在阻止你。

      如果您使用常规类型返回,问题会消失吗?我猜是必须的。

      【讨论】:

      • 罗布,我不这么认为。主要问题是它适用于许多其他场景。我不知道为什么它对此不起作用。所有 LinqOnDynamic 方法都返回动态的 IEnumerable,所以这应该不是问题。看起来它正在尝试对扩展方法进行强绑定,但我不知道如何。
      • 啊 - 动态不支持 ExtensionMethods:stackoverflow.com/questions/258988/… 我无法准确判断您在哪里使用它 - 但是扩展方法可能是问题所在。
      • 这实际上不是在动态上运行的,它是在动态的IEnumerable上运行的,这是一个静态类型,所以它可以有扩展方法。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-01-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-14
      • 1970-01-01
      • 2012-09-28
      相关资源
      最近更新 更多