lt1 lt1 - 13 days ago 7
C# Question

How can I create an "Include" overload that Includes multiple entities (passed as separate params)?

I'd like to write an overload for

Includes
that would allow me to do something like
db.Transactions.Include(t => t.Customer, t => t.Order)
rather than needing to do
db.Transactions.Include(t => t.Customer).Include(t => t.Order)
. Here's my attempt:

public static IQueryable<T> Include<T, TProperty>(this IQueryable<T> source, params Expression<Func<T, TProperty>>[] paths) {
foreach (var path in paths) {
source = QueryableExtensions.Include(source, path);
}

return source;
}


But when I try to use it, I get an error that says "The type arguments for the method cannot be inferred from the usage." Is what I'm trying to do possible?

Answer

Your method won't work as you are expecting it to. Currently, your method will expect that every expression is returning the same type, which will not work if you pass selectors for class properties of different type.

To properly handle various types, you need to change the signature of the method by removing type parameter TProperty and using Expression<Func<T, object>> as argument type.

Resulting signature should be as follows:

public static IQueryable<T> Include<T>(this IQueryable<T> source, params Expression<Func<T, object>>[] paths)

This will allow you to pass collection of various expressions to the method.

You may suspect, that it will cause problems, because you are implicitly converting the property to object, but it won't be an issue. If you examine the source code of QueryableExtensions.Include (and moving deeper to DbHelpers.TryParsePath), you will see that conversion is removed before expression is converted to string.

Comments