Ну, так как Include
возвращает IQueryable<T>
(LINQ цепочка), я бы использовал простой метод расширения:
public static IQueryable<T> WithIncludes<T>(this IQueryable<T> source, string[] associations)
{
var query = (ObjectQuery<T>)source;
foreach (var assoc in associations)
{
query = query.Include(assoc);
}
}
Тогда ваш запрос выглядит так:
var inclusions = new[] { "Tests.Course", "Tests.TestEvents" };
var result = ctx.AppUsers
.WithIncludes(inclusions)
.Where(x => x.Login.ToLower() == loginName.ToLower())
.Where(x => !x.IsDeleted)
.FirstOrDefault();
Чтобы получить строгую типизацию в отношении природы магической строки include, у меня есть специализированные перечисления для всех ассоциаций, поэтому я пропускаю через них [] и преобразую перечисление в строку include.
Дело в том, что ваши методы должны определять, какие включения требуются. Итак, первое, что вы делаете в методе, это объявляете, какие ассоциации требуются, а затем передаете это в свой метод расширения.
Это то, что вы после?