After using Reflector to evaluate how the compiler generated the linq statement, here's how I ended up creating the expression for the sub-select...
ParameterExpression transactionParameter = Expression.Parameter(typeof(FinancialTransaction), "t");
MemberExpression authorizedPersonIdProperty = Expression.Property(transactionParameter, "AuthorizedPersonId");
MemberExpression transactionDateTime = Expression.Property(transactionParameter,"TransactionDateTime");
MethodInfo whereMethod = GetWhereMethod();
MethodInfo maxMethod = GetMaxMethod();
var personIdCompare = new Expression[] {
Expression.Constant(transactions),
Expression.Lambda<Func<FinancialTransaction, bool>>( Expression.Equal(authorizedPersonIdProperty, Expression.Convert(idProperty, typeof(int?))), new ParameterExpression[] { transactionParameter } )
};
var transactionDate = Expression.Lambda<Func<FinancialTransaction, DateTime?>>( transactionDateTime, new ParameterExpression[] { transactionParameter } );
var lastTransactionDate = Expression.Call( null, maxMethod, new Expression[] { Expression.Call( null, whereMethod, personIdCompare ), transactionDate } );
...
bindings.Add( Expression.Bind( dynamicType.GetField( "LastTransaction" ), lastTransactionDate ) );
...
private MethodInfo GetWhereMethod()
{
Func<FinancialTransaction, bool> fake = element => default( bool );
Expression<Func<IEnumerable<FinancialTransaction>, IEnumerable<FinancialTransaction>>> lamda = list => list.Where( fake );
return ( lamda.Body as MethodCallExpression ).Method;
}
private MethodInfo GetMaxMethod()
{
Func<FinancialTransaction, DateTime?> fake = element => default( DateTime? );
Expression<Func<IEnumerable<FinancialTransaction>, DateTime?>> lamda = list => list.Max( fake );
return ( lamda.Body as MethodCallExpression ).Method;
}