views:

84

answers:

1

I have some code for strongly typing Includes()'s in linq, like so...

public static ObjectQuery<T> Include<T>(this ObjectQuery<T> mainQuery, Expression<Func<T, object>> subSelector)
    {
        return mainQuery.Include(((subSelector.Body as MemberExpression).Member as System.Reflection.PropertyInfo).Name);
    }

    /// <summary>
    /// Old way: (from dbUser in DataSource.DataContext.Users.Include("UserSubscriptions.ChurchSubscriptions") select dbUser);
    /// New way: (from dbUser in DataSource.DataContext.Users.Include<Users, UserSubscriptions>(u => u.UserSubscriptions, s => s.ChurchSubscriptions) select dbUser);
    /// </summary>
    public static ObjectQuery<T> Include<T, Q>(this ObjectQuery<T> mainQuery, Expression<Func<T, object>> tSubSelector, Expression<Func<Q, object>> qSubSelector)
    {
        string tProperty = ((tSubSelector.Body as MemberExpression).Member as System.Reflection.PropertyInfo).Name;
        string qProperty = ((qSubSelector.Body as MemberExpression).Member as System.Reflection.PropertyInfo).Name;
        string path = string.Format("{0}.{1}", tProperty, qProperty);
        return mainQuery.Include(path);
    }

My question is, is there anyway I can write a more generic function account for any level of successive includes? Rather than having to rewrite it for say 3, 4, etc include types?

+1  A: 

I guess by successive includes you mean additional sub selectors.

If so, then the following function uses a parameter array for the additional sub selectors (after the first one) while maintaining that the first expression is tied to the same type T as the other ones.

public static ObjectQuery<T> Include<T>(this ObjectQuery<T> mainQuery, Expression<Func<T, object>> tSubSelector, params Expression<Func<object, object>>[] subSelectors)
{
    var pathBuilder = new StringBuilder(((PropertyInfo)((MemberExpression)tSubSelector.Body).Member).Name);
    foreach (var selector in subSelectors)
    {
        pathBuilder.Append('.');
        pathBuilder.Append(((PropertyInfo)((MemberExpression)selector.Body).Member).Name);
    }

    return mainQuery.Include(pathBuilder.ToString());
}
Thomas Gerstendörfer
do you think you could provide a brief example of using it? I'm having trouble testing it out
f0ster