System.Linq.Dynamic.Core icon indicating copy to clipboard operation
System.Linq.Dynamic.Core copied to clipboard

Nested parameters

Open zspitz opened this issue 5 years ago • 2 comments

Given the following hierarchy:

public class Person {
    public string Name {get; set;}
    public Post[] Posts {get;set;}
}
public class Post {
    public string Text {get;set;}
    public string[] Tags {get;set;}
}

how can I write the equivalent of the following query:

var lst = new List<Person>();
var qry = lst.AsQueryable().Where(p => p.Posts.Any(p1 => p1.Text.Contains(p.Name)));

I've seen the use of outerIt to refer to the outer parameter, but the following code:

var selector = "Posts.Any(Text = outerIt.Name)";
var prm = Parameter(typeof(Person));
var parser = new ExpressionParser(new[] { prm }, selector, new object[] { }, ParsingConfig.Default);

fails with:

System.Linq.Dynamic.Core.Exceptions.ParseException: 'No property or field 'outerIt' exists in type 'Post''

An additional question: what happens if an additional level of parameter is required? e.g. the equivalent of:

var qry = lst.AsQueryable().Where(
    p => p.Posts.Any(
        p1 => p1.Tags.Any( 
            t => t.Contains(p.Name) || p1.C.ontains(p.Name)
        )
    )
);

zspitz avatar Oct 22 '20 21:10 zspitz

@StefH Just wondering, is referring to an outer predicate possible?

var test = context.Set<MyEntity1>()
    .Select(a => new MyItem { 
        Name = context.Set<MyEntity2>()
            .where("b => b.Prop == a.Prop")
            .FirstOrDefault()
            .Name
     });

Perhaps related to the original question, what is the it in this line?

mrlife avatar Apr 19 '21 14:04 mrlife

@mrlife What do you think of numbered its, starting from the outermost parameter? In other words, the equivalent of this:

var qry = lst.AsQueryable().Where(
    p => p.Posts.Any(
        p1 => p1.Tags.Any( 
            t => p.Name.Contains(t) || p1.Text.Contains(t)
        )
    )
);

might be written as this:

var qry = lst.AsQueryable.Where("Posts.Any(Tags.Any(it.Name.Contains(it2) || it1.Text.Contains(it2)");

zspitz avatar May 10 '21 05:05 zspitz