Динамичный + 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 };

Это только, когда я добавляю:

где тег. ReferencedAggregate! = пустой указатель

То, что я получаю ошибку две строки прежде:

где объект. Теги! = пустой указатель//ОШИБКА КОМПИЛЯТОРА ЗДЕСЬ

Не уверенный, что продолжается

19
задан Ayende Rahien 9 August 2010 в 23:14
поделиться

3 ответа

Если я попытаюсь просто преобразовать ваши вызовы в:

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.

13
ответ дан 30 November 2019 в 05:04
поделиться
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 };

Это немного лучше. Не идеально, но это похоже на начало - вы можете пройти только определенное количество уровней, прежде чем заблудитесь в подвешенном состоянии.

2
ответ дан 30 November 2019 в 05:04
поделиться

Возвращаемый анонимный тип - <> h__TransparentIdentifier0 и обрабатывается компилятором во время компиляции - проблема связана с «динамическим порядком приоритета» - прочтите здесь: Трудности, связанные с отсутствием метода в C # 4.0: динамический vs RealProxy

Я только что прошел через это сегодня, работая над недавним постом. Я немного догадываюсь и скажу, что анонимный тип подготовлен после динамического присваивания :) - компилятор знает это и мешает вам.

Исчезнет ли проблема, если вы воспользуетесь возвратом обычного типа? Полагаю, это должно быть.

1
ответ дан 30 November 2019 в 05:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: