Linq - соединение слева при нескольких (ИЛИ) условиях

Другое событие NullPointerException возникает, когда объявляется массив объектов, а затем сразу же пытается разыменовать его внутри.

String[] phrases = new String[10];
String keyPhrase = "Bird";
for(String phrase : phrases) {
    System.out.println(phrase.equals(keyPhrase));
}

Этот конкретный NPE можно избежать, если порядок сравнения отменяется ; а именно, использовать .equals для гарантированного непустого объекта.

Все элементы внутри массива инициализируются их общим начальным значением ; для любого типа массива объектов, это означает, что все элементы null.

Вы должны инициализировать элементы в массиве перед доступом или разыменованием их.

String[] phrases = new String[] {"The bird", "A bird", "My bird", "Bird"};
String keyPhrase = "Bird";
for(String phrase : phrases) {
    System.out.println(phrase.equals(keyPhrase));
}

25
задан Gilad Green 5 December 2017 в 19:04
поделиться

2 ответа

LINQ напрямую поддерживает только эквисоединения. Если вы хотите выполнить какое-либо другое соединение, вам в основном потребуется перекрестное соединение и где :

from a in tablea
from b in tableb
where a.col1 == b.col1 || a.col2 == b.col2
select ...

Вероятно, стоит проверить, как выглядит сгенерированный SQL и каков план запроса. Могут быть более эффективные способы сделать это, но это, вероятно, самый простой подход.

Возможно, стоит проверить, как выглядит сгенерированный SQL и каков план запроса. Могут быть более эффективные способы сделать это, но это, вероятно, самый простой подход.

Возможно, стоит проверить, как выглядит сгенерированный SQL и каков план запроса. Могут быть более эффективные способы сделать это, но это, вероятно, самый простой подход.

36
ответ дан 28 November 2019 в 04:54
поделиться

В зависимости от поставщика запроса вы можете просто использовать два предложения from:

from a in tablea
from b in tableb 
where a.col1 == b.col1 || a.col2 == b.col2

Что, если вы выполняете в БД, будет столь же эффективным. Если вы выполняете в памяти (Linq to Objects), это перечислит все возможные комбинации, которые могут быть неэффективными.

Arg, Skeeted; -).

Возможны более эффективные альтернативы Linq to Objects. Оператор join перечисляет каждый источник только один раз, а затем выполняет хэш-соединение, так что вы можете разделить предложение or на два отдельных соединения, а затем взять их объединение. Объединение в linq - это просто конкатенация без дубликатов, поэтому это будет выглядеть следующим образом:

(from a in tablea
join b in tableb on a.Col1 equals b.Col1
select new {a, b})
.Concat(
from a in tablea
join b in tableb on a.Col2 equals b.Col2
select new {a, b}
).Distinct()

Этот подход работает, и это всего лишь один запрос, но он несколько неочевиден в том смысле, что характеристики производительности кода зависят от понимания подробно как работает linq. Лично, если вы хотите выполнить хэш-соединение с потенциально множественными совпадениями, более очевидным инструментом является ToLookup . Альтернативный вариант использования может выглядеть следующим образом:

var bBy1 = tableb.ToLookup(b=>b.Col1);
var bBy2 = tableb.ToLookup(b=>b.Col2);
var q3 = 
    from a in tablea
    from b in bBy1[a.Col1].Concat(bBy2[a.Col2]).Distinct()
    ...

Это решение на самом деле короче, а причина его работы более очевидна, поэтому я бы предпочел именно его. Просто помните, что если вы разделите оператор || на два отдельных запроса, как в двух вышеупомянутых сценариях, вам необходимо вручную избежать двойного подсчета результатов (например, использовать Distinct ).

(from a in tablea
join b in tableb on a.Col1 equals b.Col1
select new {a, b})
.Concat(
from a in tablea
join b in tableb on a.Col2 equals b.Col2
select new {a, b}
).Distinct()

Этот подход работает, и это всего лишь один запрос, но он несколько неочевиден в том смысле, что характеристики производительности кода зависят от детального понимания того, как работает linq. Лично, если вы хотите выполнить хэш-соединение с потенциально множественными совпадениями, более очевидным инструментом является ToLookup . Альтернативный вариант использования может выглядеть следующим образом:

var bBy1 = tableb.ToLookup(b=>b.Col1);
var bBy2 = tableb.ToLookup(b=>b.Col2);
var q3 = 
    from a in tablea
    from b in bBy1[a.Col1].Concat(bBy2[a.Col2]).Distinct()
    ...

Это решение на самом деле короче, а причина его работы более очевидна, поэтому я бы предпочел именно его. Просто помните, что если вы разделите оператор || на два отдельных запроса, как в двух вышеупомянутых сценариях, вам необходимо вручную избежать двойного подсчета результатов (т.е. использовать Distinct ).

(from a in tablea
join b in tableb on a.Col1 equals b.Col1
select new {a, b})
.Concat(
from a in tablea
join b in tableb on a.Col2 equals b.Col2
select new {a, b}
).Distinct()

Этот подход работает, и это всего лишь один запрос, но он несколько неочевиден в том смысле, что характеристики производительности кода зависят от детального понимания того, как работает linq. Лично, если вы хотите выполнить хэш-соединение с потенциально множественными совпадениями, более очевидным инструментом является ToLookup . Альтернативный вариант использования может выглядеть следующим образом:

var bBy1 = tableb.ToLookup(b=>b.Col1);
var bBy2 = tableb.ToLookup(b=>b.Col2);
var q3 = 
    from a in tablea
    from b in bBy1[a.Col1].Concat(bBy2[a.Col2]).Distinct()
    ...

Это решение на самом деле короче, а причина его работы более очевидна, поэтому я бы предпочел именно его. Просто помните, что если вы разделите оператор || на два отдельных запроса, как в двух вышеупомянутых сценариях, вам необходимо вручную избежать двойного подсчета результатов (т.е. использовать Distinct ).

Это несколько неочевидно в том смысле, что характеристики производительности кода зависят от детального понимания того, как работает linq. Лично, если вы хотите выполнить хэш-соединение с потенциально множественными совпадениями, более очевидным инструментом является ToLookup . Альтернативный вариант использования может выглядеть следующим образом:

var bBy1 = tableb.ToLookup(b=>b.Col1);
var bBy2 = tableb.ToLookup(b=>b.Col2);
var q3 = 
    from a in tablea
    from b in bBy1[a.Col1].Concat(bBy2[a.Col2]).Distinct()
    ...

Это решение на самом деле короче, а причина его работы более очевидна, поэтому я бы предпочел именно его. Просто помните, что если вы разделите оператор || на два отдельных запроса, как в двух вышеупомянутых сценариях, вам необходимо вручную избежать двойного подсчета результатов (т.е. использовать Distinct ).

Это несколько неочевидно в том смысле, что характеристики производительности кода зависят от детального понимания того, как работает linq. Лично, если вы хотите выполнить хэш-соединение с потенциально множественными совпадениями, более очевидным инструментом является ToLookup . Альтернативный вариант использования может выглядеть следующим образом:

var bBy1 = tableb.ToLookup(b=>b.Col1);
var bBy2 = tableb.ToLookup(b=>b.Col2);
var q3 = 
    from a in tablea
    from b in bBy1[a.Col1].Concat(bBy2[a.Col2]).Distinct()
    ...

Это решение на самом деле короче, а причина его работы более очевидна, поэтому я бы предпочел именно его. Просто помните, что если вы разделите оператор || на два отдельных запроса, как в двух вышеупомянутых сценариях, вам необходимо вручную избежать двойного подсчета результатов (т.е. использовать Distinct ).

Альтернативный вариант использования может выглядеть следующим образом:

var bBy1 = tableb.ToLookup(b=>b.Col1);
var bBy2 = tableb.ToLookup(b=>b.Col2);
var q3 = 
    from a in tablea
    from b in bBy1[a.Col1].Concat(bBy2[a.Col2]).Distinct()
    ...

Это решение на самом деле короче, а причина его работы более очевидна, поэтому я бы предпочел именно его. Просто помните, что если вы разделите оператор || на два отдельных запроса, как в двух вышеупомянутых сценариях, вам необходимо вручную избежать двойного подсчета результатов (например, использовать Distinct ).

Альтернативный вариант использования может выглядеть следующим образом:

var bBy1 = tableb.ToLookup(b=>b.Col1);
var bBy2 = tableb.ToLookup(b=>b.Col2);
var q3 = 
    from a in tablea
    from b in bBy1[a.Col1].Concat(bBy2[a.Col2]).Distinct()
    ...

Это решение на самом деле короче, а причина его работы более очевидна, поэтому я бы предпочел именно его. Просто помните, что если вы разделите оператор || на два отдельных запроса, как в двух вышеупомянутых сценариях, вам необходимо вручную избежать двойного подсчета результатов (т.е. использовать Distinct ).

21
ответ дан 28 November 2019 в 04:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: