Что Вы ищете выполнимо, но не так, как вы пробовали, потому что прошел лямбда-выражение не может быть использован непосредственно внутри другого лямбда-выражения.
Начните сначала, создав универсальный класс для хранения ключа группировки. Это похоже на систему при условии Tuple
, но имеет конструктор без параметров и простое свойство получить/сеттеры, чтобы соответствовать правилам проекционных EF:
public class GroupKey<K1, K2>
{
public K1 Key1 { get; set; }
public K2 Key2 { get; set; }
}
Затем вам нужно построить динамически лямбда-выражения, как этот
Expression<Func<T, K1, K2>> keySelector = x =>
new GroupKey<K1, K2> { Key1 = x.Prop1, Key2 = x.Prop2 };
В для того чтобы сделать это, вы будете нуждаться в некоторых Expression
помощниках:
public static class ExpressionUtils
{
public static Expression ReplaceParameter(this Expression expression, ParameterExpression source, Expression target)
{
return new ParameterReplacer { Source = source, Target = target }.Visit(expression);
}
class ParameterReplacer : ExpressionVisitor
{
public ParameterExpression Source;
public Expression Target;
protected override Expression VisitParameter(ParameterExpression node)
{
return node == Source ? Target : base.VisitParameter(node);
}
}
}
и вы можете инкапсулировать группировку части в переменном токе Выборочный метод расширения:
public static class QueryableExtensions
{
public static IQueryable<IGrouping<GroupKey<K1, K2>, T>> GroupByPair<T, K1, K2>(this IQueryable<T> source, Expression<Func<T, K1>> keySelector1, Expression<Func<T, K2>> keySelector2)
{
var parameter = keySelector1.Parameters[0];
var key1 = keySelector1.Body;
var key2 = keySelector2.Body.ReplaceParameter(keySelector2.Parameters[0], parameter);
var keyType = typeof(GroupKey<K1, K2>);
var keySelector = Expression.Lambda<Func<T, GroupKey<K1, K2>>>(
Expression.MemberInit(
Expression.New(keyType),
Expression.Bind(keyType.GetProperty("Key1"), key1),
Expression.Bind(keyType.GetProperty("Key2"), key2)),
parameter);
return source.GroupBy(keySelector);
}
}
Наконец, существенная часть вашего метода становится так:
toto = db.companyDBSET
.GroupByPair(p => p.Founded_Year, myGroupingProperty)
.Select(g => new timelineResult
{
year = g.Key.Key1,
cluster = g.Key.Key2.ToString(),
count = g.Count()
})
.OrderBy(o => o.year)
.ToList();
Что * точно * этим сообщение об ошибке? –
Было бы также полезно предоставить [mcve], а не просто фрагмент. –
Это не может работать, вы используете в лямбда, вы пытаетесь сделать что-то вроде: 'p => new {p.Founded_Year, p2 => p2.PropertyToGroupBy}' с вложенными lambdas. Вам, вероятно, придется использовать деревья выражений для этого или предоставить полный параметр 'p => new {p.Founded_Year, myGroupingProperty} как параметр, а не только одну часть ключа (создание класса/структуры, t должен работать с анонимным типом для ключа). –