Ошибка компиляции Dynamic + linq
Я скажу заранее, что делаю некоторые ужасные вещи с 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 };
Только когда я добавляю:
где tag.ReferencedAggregate!= null
Я получаю сообщение об ошибке:
где entity.Tags!= null//ОШИБКА КОМПЬЮТЕРА ЗДЕСЬ
Не уверен, что происходит
Ответы
Ответ 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)
Я получаю другую ошибку компилятора, которая, возможно, показывает, что происходит:
'Невозможно использовать лямбда-выражение в качестве аргумента для динамически отправленной операции, не введя его прежде всего в класс делегата или дерева выражений
Итак, я думаю, вам нужно перегрузить оператор Where.
Ответ 2
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 };
Это немного лучше. Не идеально, но это похоже на начало - вы можете пройти столько уровней, пока не потеряете себя в подвешенном состоянии.
Ответ 3
Анонимный тип return is < > h__TransparentIdentifier0 и обрабатывается компилятором во время компиляции - проблема возникает в "динамическом порядке приоритета" - читайте здесь:
Метод-недостающие трудности в С# 4.0: динамический vs RealProxy
Я только что прошел через это сегодня, заняв последнее сообщение. У меня будет небольшая догадка и скажу, что анонимный тип готов после динамического назначения:) - компилятор знает об этом и мешает вам.
Устранена ли проблема, если вы используете регулярный возврат типа? Я предполагаю, что это должно быть.