Dynamic + linq compilation error
我会在前面说,我正在用动态数据上的LINQ做一些非常可怕的事情。但我不明白为什么这个查询不能编译:
错误1属性"<>h_u transparentIdentifier0"不能与类型参数一起使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | public class Program { public static void Main(string[] args) { var docs = new dynamic[0]; var q = from doc in docs where doc["@metadata"]["Raven-Entity-Name"] =="Cases" where doc.AssociatedEntities != null from entity in doc.AssociatedEntities where entity.Tags != null // COMPILER ERROR HERE from tag in entity.Tags where tag.ReferencedAggregate != null select new {tag.ReferencedAggregate.Id, doc.__document_id}; } } public static class LinqOnDynamic { private static IEnumerable<dynamic> Select(this object self) { if (self == null) yield break; if (self is IEnumerable == false || self is string) throw new InvalidOperationException("Attempted to enumerate over" + self.GetType().Name); foreach (var item in ((IEnumerable) self)) { yield return item; } } public static IEnumerable<dynamic> SelectMany(this object source, Func<dynamic, int, IEnumerable<dynamic>> collectionSelector, Func<dynamic, dynamic, dynamic> resultSelector) { return Enumerable.SelectMany(Select(source), collectionSelector, resultSelector); } public static IEnumerable<dynamic> SelectMany(this object source, Func<dynamic, IEnumerable<dynamic>> collectionSelector, Func<dynamic, dynamic, dynamic> resultSelector) { return Enumerable.SelectMany(Select(source), collectionSelector, resultSelector); } public static IEnumerable<dynamic> SelectMany(this object source, Func<object, IEnumerable<dynamic>> selector) { return Select(source).SelectMany<object, object>(selector); } public static IEnumerable<dynamic> SelectMany(this object source, Func<object, int, IEnumerable<dynamic>> selector) { return Select(source).SelectMany<object, object>(selector); } } |
为了增加对伤害的侮辱,以下工作:
1 2 3 4 5 6 7 8 |
只有当我加上:
其中tag.referencedAggregate!=空
我之前有两行出错:
哪里实体。标签!=空//此处出现编译器错误
不知道发生了什么事
如果我尝试将您的呼叫转换为:
1 2 | 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操作符过载。
1 2 3 4 5 6 7 8 9 10 | var q = from doc in docs where doc["@metadata"]["Raven-Entity-Name"] =="Cases" where doc.AssociatedEntities != null from entity in ((IEnumerable<dynamic>)doc.AssociatedEntities) .Where(entity => entity.Tags != null) from tag in ((IEnumerable<dynamic>)entity.Tags) .Where(tag => tag.ReferencedAggregate != null) select new { tag.ReferencedAggregate.Id, doc.__document_id }; |
好一点。不完美,但这就像《盗梦空间》——在你陷入困境之前,你只能深入到很多层面。
匿名类型返回是<>h_u transparentIdentifier0,由编译器在编译时处理-问题似乎是"动态优先顺序"-请阅读以下内容:方法在C 4.0中缺少困难:动态与realproxy
我今天刚读了一篇最近的文章。我将有一个小小的猜测,并说匿名类型是在动态分配之后准备好的:)-编译器知道这一点,并且正在阻挠您。
如果使用常规类型的返回,问题是否会消失?我想是必须的。