Мне действительно пришлось придумать собственное решение этой проблемы, потому что я имею дело с источником данных, который НЕ совместим с Entity Framework (DBase 4 на odbc-соединении), который имеет довольно много-много табличных отношенийи вместо того, чтобы выписывать длинные вытянутые объединения и групповые блоки linq, я создал два метода расширения
Теперь учтите, что я имею дело только с одним направлением чтения из источника данных по существу в набор данныхэта программа предназначена только для исторических данных и не принимает новый ввод или изменения, поэтому я не уверен, насколько хорошо эти методы расширения будут выдерживать любые обновления или вставки или удаления актуальных обновлений данных и т. д.
(I 'мы обернули каждый параметр в свою строку для удобства чтения)
public static IEnumerable<TResult> ManyToManyGroupBy
<TLeft, TRight, TMiddle, TLeftKey, TRightKey, TGroupKey, TResult>
(
this IEnumerable<TLeft> Left,
IEnumerable<TRight> Right,
IEnumerable<TMiddle> Middle,
Func<TLeft, TLeftKey> LeftKeySelector,
Func<TMiddle, TLeftKey> MiddleLeftKeySelector,
Func<TRight, TRightKey> RightKeySelector,
Func<TMiddle, TRightKey> MiddleRightKeySelector,
Func<TLeft, TGroupKey> GroupingSelector,
Func<TGroupKey, IEnumerable<TRight>, TResult> Selector
)
{
return Left
.Join(Middle, LeftKeySelector, MiddleLeftKeySelector, (L, M) => new { L, M })
.Join(Right, LM => MiddleRightKeySelector(LM.M), RightKeySelector, (LM, R) => new { R, LM.L })
.GroupBy(LR => GroupingSelector(LR.L))
.Select(G => Selector(G.Key, G.Select(g => g.R)));
}
public static IEnumerable<TResult> ManyToManySelect
<TLeft, TRight, TMiddle, TLeftKey, TRightKey, TResult>
(
this IEnumerable<TLeft> Left,
IEnumerable<TRight> Right,
IEnumerable<TMiddle> Middle,
Func<TLeft, TLeftKey> LeftKeySelector,
Func<TMiddle, TLeftKey> MiddleLeftKeySelector,
Func<TRight, TRightKey> RightKeySelector,
Func<TMiddle, TRightKey> MiddleRightKeySelector,
Func<TLeft, TRight, TResult> Selector
)
{
return Left
.Join(Middle, LeftKeySelector, MiddleLeftKeySelector, (L, M) => new { L, M })
.Join(Right, LM => MiddleRightKeySelector(LM.M), RightKeySelector, (LM, R) => new { R, LM.L })
.Select(LR => Selector(LR.L, LR.R));
}
Это довольно длинные методы, но они охватывают объединение двух таблиц через среднюю таблицу, а также группирование по любому конкретному элементу Left или свойству объекта.оставленный элемент
Использование их будет выглядеть примерно так (Как и выше, я обернул каждый параметр в отдельной строке для удобства чтения)
var EmployeesCoursesTest = Employees.ManyToManySelect
(
Courses,
CourseParticipations,
E => E.SS,
CP => CP.SS,
C => C.EVENTNO,
CP => CP.EVENTNO,
(E, C) => new
{
C.EVENTNO,
C.START_DATE,
C.END_DATE,
C.HOURS,
C.SESSIONS,
Trainings.First(T => T.TRGID == C.TRGID).TRAINING,
Instructors.First(I => I.INSTRUCTID == C.INSTRUCTID).INSTRUCTOR,
Locations.First(L => L.LOCATIONID == C.LOCATIONID).LOCATION,
Employee = E
}
);
var EmployeesCoursesGroupByTest = Employees.ManyToManyGroupBy
(
Courses,
CourseParticipations,
E => E.SS,
CP => CP.SS,
C => C.EVENTNO,
CP => CP.EVENTNO,
E => E,
(E, Cs) => new
{
Employee = E,
Courses = Cs
}
);
Возможно, это поможет вам, я сам стараюсь держаться подальше от синтаксиса запроса, поэтому я работаю почти исключительно с синтаксисом методаLinq, так что написание таких методов расширения - это просто способ, которым я думаю сейчас.