关于c#:Dynamic + linq编译错误

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
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!=空

我之前有两行出错:

哪里实体。标签!=空//此处出现编译器错误

不知道发生了什么事


如果我尝试将您的呼叫转换为:

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

我今天刚读了一篇最近的文章。我将有一个小小的猜测,并说匿名类型是在动态分配之后准备好的:)-编译器知道这一点,并且正在阻挠您。

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