Thursday, May 31, 2018

c# - Dynamic + linq compilation error



I'll say up front that I am doing some really scary things with linq on dynamic data.
But I can't figure out why this query fails to compile:



Error 1 The property '<>h__TransparentIdentifier0' cannot be used with type arguments




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 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 SelectMany(this object source,
Func> collectionSelector,
Func resultSelector)
{
return Enumerable.SelectMany(Select(source), collectionSelector, resultSelector);
}

public static IEnumerable SelectMany(this object source,
Func> collectionSelector,
Func resultSelector)

{
return Enumerable.SelectMany(Select(source), collectionSelector, resultSelector);
}

public static IEnumerable SelectMany(this object source,
Func> selector)
{
return Select(source).SelectMany(selector);
}


public static IEnumerable SelectMany(this object source,
Func> selector)
{
return Select(source).SelectMany(selector);

}
}


To add insult to injury, the following works:





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 };



It is only when I add:



where tag.ReferencedAggregate != null



That I get an error two lines before:



where entity.Tags != null // COMPILER ERROR HERE




Not sure what is going on


Answer



If I try just converting your calls to:



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)


I get a different compiler error which perhaps reveals what is going on:




'Cannot use a lambda expression as an argument to a dynamically dispatched operation without first casting it to a delegate or expression tree type'



So I guess you have to overload the Where operator.


No comments:

Post a Comment

plot explanation - Why did Peaches&#39; mom hang on the tree? - Movies &amp; TV

In the middle of the movie Ice Age: Continental Drift Peaches' mom asked Peaches to go to sleep. Then, she hung on the tree. This parti...