Я скажу впереди, что делаю некоторые действительно страшные вещи с linq на динамических данных. Но я не могу выяснить, почему этому запросу не удается скомпилировать:
Ошибка 1 свойство' <> h __ TransparentIdentifier0' не может использоваться с аргументами типа
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); } }
Добавить оскорбление травмы, следующих работ:
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 from tag in entity.Tags select new { tag.ReferencedAggregate.Id, doc.__document_id };
Это только, когда я добавляю:
где тег. ReferencedAggregate! = пустой указатель
То, что я получаю ошибку две строки прежде:
где объект. Теги! = пустой указатель//ОШИБКА КОМПИЛЯТОРА ЗДЕСЬ
Не уверенный, что продолжается
Если я попытаюсь просто преобразовать ваши вызовы в:
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)
, я получаю другую ошибку компилятора, которая, возможно, показывает, что происходит:
'Нельзя использовать лямбда-выражение в качестве аргумента для динамически отправляемая операция без предварительного приведения ее к типу делегата или дерева выражения '
Так что, я думаю, вам нужно перегрузить оператор Where.
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__TransparentIdentifier0 и обрабатывается компилятором во время компиляции - проблема связана с «динамическим порядком приоритета» - прочтите здесь: Трудности, связанные с отсутствием метода в C # 4.0: динамический vs RealProxy
Я только что прошел через это сегодня, работая над недавним постом. Я немного догадываюсь и скажу, что анонимный тип подготовлен после динамического присваивания :) - компилятор знает это и мешает вам.
Исчезнет ли проблема, если вы воспользуетесь возвратом обычного типа? Полагаю, это должно быть.