WAQS Querying: Calculated properties and dependences

7 reasons to use WAQS

WAQS documentation

 

You perhaps saw in the previous post, WAQS adds a partial method to change the generated expression. In the future, when L2E to L2O switching will work, you could define it to return null if the expression is not usable in L2E.

In addition, sometimes, because of SQL aspects, you could want to use a different expression for L2E calculation (without any null test for example).

So you can use this partial method.

Now we will add this new specification method:

public static string GetCustomerName(this Order o)
{
    return o.Customer.GetCustomerName();
}


The GetCustomerName method on Order depends on the GetCustomerName on Customer. So if we want to redefine the Customer GetCustomerName expression using partial method, we have to use this new expression to calculate Order CustomerName.



 



So, how does it work?



WAQS uses a fake expression that it replaces then by the Customer GetCustomerNameExpression one:



protected internal static Expression<Func<WebApplication25.Order, string>> GetCustomerNameExpression
    (
bool isCoalesceEnabled = true)
{
    Func<WebApplication25.Customer, string> getCustomerName_Customer = (_) => default(string);
    Expression<Func<WebApplication25.Order, string>> exp = (o) => getCustomerName_Customer(o.Customer);
    Func<Expression, Expression> replaceExpFunc = null;
    replaceExpFunc = e =>
        {
            var invocationExpression = e as InvocationExpression;
            MemberExpression memberExpression;
            if (invocationExpression == null || 
                (memberExpression = invocationExpression.Expression
as MemberExpression) == null)
               
return e;
            switch (memberExpression.Member.Name)
            {
                case "getCustomerName_Customer"
                { 
                   
var getCustomerName_CustomerSubExp =  
                       
CustomerDALSpecifications.GetCustomerNameExpression (isCoalesceEnabled : false); 
                    if (getCustomerName_CustomerSubExp == null
                       
return null
                    Expression subExp = getCustomerName_CustomerSubExp.Body 
                        .Replace(getCustomerName_CustomerSubExp.Parameters[0],  
                            replaceExpFunc(invocationExpression.Arguments[0]));
                    return subExp; 
                }
                default:
                    return e;
            }
         };
    exp = (Expression<Func<WebApplication25.Order, string>>)exp.Replace(replaceExpFunc);
    GetCustomerNameExpression (ref exp);
    return exp;
}









In order to avoid a complex analyze in WAQS to build the ExpressionTree at code generation, this way is easier with an insignificant cost at runtime.



However, in the future, WAQS we could think about this optimization.

This entry was posted in 12253, 16868, 7674. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>