2010-02-05 8 views
5

ich einige Code haben für stark Typisierung Includes() 's in Linq, wie so ...Abfrage Erweiterung für LINQ

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); 
    } 

Meine Frage ist, ist es trotzdem ich eine generische Funktion Konto schreiben kann Jede Ebene der aufeinander folgenden umfasst? Anstatt es für sagen 3, 4 usw. neu schreiben zu müssen, gehören Typen?

Antwort

2

Ich denke, durch sukzessive umfasst Sie zusätzliche Subselektoren.

Wenn dies der Fall ist, verwendet die folgende Funktion ein Parameter-Array für die zusätzlichen Unterselektoren (nach dem ersten), wobei der erste Ausdruck mit dem gleichen Typ T wie die anderen verknüpft ist.

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()); 
}