Справка по пониманию Enumerable.Join Method
Вчера я разместил этот вопрос относительно использования lambdas внутри метода Join(), чтобы проверить, существует ли 2 условия для двух объектов. Я получил ответ на вопрос, который работал отлично. Я подумал, прочитав статью MSDN по методу Enumerable.Join(), я бы точно понял, что происходит, но я этого не делаю. Может ли кто-нибудь помочь мне понять, что происходит в приведенном ниже коде (метод Join())? Спасибо заранее.
if (db.TableA.Where( a => a.UserID == currentUser )
.Join( db.TableB.Where( b => b.MyField == someValue ),
o => o.someFieldID,
i => i.someFieldID,
(o,i) => o )
.Any())
{
//...
}
Изменить:
В частности, мне интересно узнать о последних трех параметрах и о том, что происходит на самом деле. Как они приводят к требованиям подписи Func (TOuter, TKey), Func (TInner, TKey) и т.д.
Ответы
Ответ 1
Эрик и Ник дали хорошие ответы.
Вы также можете написать выражение запроса Linq, используя синтаксис запроса (синтаксис синтаксиса, который вы используете в своем примере):
var query = from a in db.TableA
join b in db.TableB on a.someFieldID equals b.someFieldID
where a.UserID == currentUser && b.MyField == someValue
select a;
if (query.Any()) {
...
}
Update:
Вы, кажется, застряли на лямбда-выражениях. Это функция, которую вы проходите как переменная. Выражение лямбда эквивалентно анонимному делегату (или анонимному методу, для меня более общим).
Вот ваш запрос с лямбда-выражениями в качестве делегатов (замените EntityType на тип вашего объекта, возвращенный из TableA, конечно):
if (db.TableA.Where( delegate(EntityType a) { return a.UserID == currentUser; } )
.Join( db.TableB.Where( delegate(EntityType b) { return b.MyField == someValue; } ),
delegate(EntityType o) { return o.somefieldId); },
delegate(EntityType i) { return i.someFieldId); },
delegate(EntityType o, EntityType i) { return o; })
.Any())
{ //...
}
ПРИМЕЧАНИЕ. Выражение лямбда имеет важные аспекты, которые делают его более чем эквивалентным для анонимных методов. Я рекомендую вам просмотреть другие вопросы SO и прочитать онлайн о лямбда-выражениях в частности. Они позволяют выражать очень сильные идеи в гораздо более простом и элегантном стиле. Это глубокая тема, но основы достаточно легки для понимания. Это функция, которую вы можете передавать как переменную, или как параметр для других функций.
Ответ 2
Синтаксис соединения
FirstTable.Join(SecondTable, FirstTableKeyExtractor, SecondTableKeyExtractor, Selector)
Итак, у вас есть две таблицы. У вас есть ключ, который является общим для обеих таблиц. Вы предоставляете два ключевых экстрактора, которые знают, как получить ключ из каждой строки в таблице.
Логика объединения идентифицирует пары строк, по одному из каждой таблицы, которые имеют один и тот же ключ.
Каждая из этих строк затем запускается через селектор, чтобы спроецировать результат.
Отвечает ли это на ваш вопрос?
Ответ 3
Объяснение соединения.
b
= тип объекта первой таблицы
o
= тип объекта первой таблицы
i
= тип объекта второй таблицы
-
db.TableB.Where( b => b.MyField == someValue )
Это тип элемента второй таблицы
-
o => o.someFieldID
Ключ первой таблицы
-
i => i.someFieldID
Ключ второй таблицы (который будет соответствовать ключу в первой таблице)
-
(o,i) => o
Объект, возвращающий в этом случае тип объекта первой таблицы.
Ответ 4
Этот запрос говорит join TableA
to TableB
где TableA.someFieldID == TableB.someFieldID
и выбирая результаты из таблицы A и видя, есть ли какие-либо результаты вообще
С точки зрения SQL, подумайте об этом так, даже если это не Linq-to-SQL... если вы знакомы с SQL, возможно, это имеет смысл:
Select Count(*)
From TableA a
Join TableB b
On a.someFieldID = b.someFieldID
Затем, если проверка Count(*)
равнa > 0