The inner lambda expression will have access to the parameters from the outer lambda expression:
var x = Expression.Parameter(typeof(Widget), "x");
var y = Expression.Parameter(typeof(Role), "y");
var z = Expression.Parameter(typeof(RoleAction), "z");
var roleActionBody = Expression.OrElse(
Expression.Not(Expression.Property(x, "IsActive")),
Expression.Property(z, "IsActive"));
var roleBody = Expression.Call(typeof(Enumerable), "Where", new[] { typeof(RoleAction) },
Expression.Property(y, "Actions"),
Expression.Lambda(roleActionBody, z));
var body = Expression.Call(typeof(Enumerable), "Select", new[] { typeof(Role), typeof(IEnumerable<RoleAction>) },
Expression.Property(x, "Roles"),
Expression.Lambda(roleBody, y));
var result = Expression.Lambda<Func<Widget, IEnumerable<IEnumerable<RoleAction>>>>(body, x);
NB: The result is a sequence of sequences of
RoleAction
objects. If you want to flatten that to a sequence of
RoleAction
objects, you'll need to use
SelectMany
:
...
var body = Expression.Call(typeof(Enumerable), "SelectMany", new[] { typeof(Role), typeof(RoleAction) },
Expression.Property(x, "Roles"),
Expression.Lambda(roleBody, y));
var result = Expression.Lambda<Func<Widget, IEnumerable<RoleAction>>>(body, x);