Лучший способ сделать этот запрос LINQ?

У меня есть несколько коллекций объектов данных, к которым нельзя получить прямой доступ друг от друга. Я полагаю, что лучшим решением было бы заставить парней из базы данных сделать запрос для этого, но в то же время есть ли способ затянуть это?

var conflicting = allFoos.Where(foo => foo.ElectronicSerialNumber != 0 
                                && foo.BarID != interestingBar.ID)
                    .Join(fooInfoCollection, foo => foo.ElectronicSerialNumber, 
                                             fooInfo => fooInfo.ElectronicID, 
                                             (foo, fooInfo) => foo)
                    .Join(allBars, foo => foo.BarID, bar => bar.ID, (foo, bar) => bar)
                    .Where(bar => bar.SomeCriteria == false)
                    .FirstOrDefault();
if (conflicting != null)
{
   doStuff(conflicting);
}               

person J Cooper    schedule 05.12.2009    source источник
comment
Не могли бы вы уточнить, является ли это LINQ to SQL или LINQ to Objects? Кроме того, есть ли у вас ограничения внешнего ключа для соединений?   -  person TrueWill    schedule 06.12.2009
comment
linq для объектов и никаких ограничений, о которых я знаю   -  person J Cooper    schedule 06.12.2009
comment
Уточняю вопрос: затянуть это может означать многое. Вы имеете в виду стиль, производительность или что-то еще?   -  person Amy B    schedule 06.12.2009
comment
Если вы просто имеете в виду синтаксис, иногда проще читать/понимать запросы, когда они написаны, если вы используете промежуточные имена переменных. Помните, что любой IQueryable не оценивается, пока вы его не перечислите.   -  person Jarrett Widman    schedule 06.12.2009
comment
@David B: Производительность, если это возможно, или более идиоматический способ, или что у вас есть. В общем, что-то в этом мне показалось не совсем правильным. Но до сих пор, кроме рекомендации по базе данных (чего я и ожидал), я не видел, чтобы кто-нибудь сказал, что вы делаете что-то неправильно, так что, возможно, такая проверка работоспособности — это все, что было нужно.   -  person J Cooper    schedule 06.12.2009


Ответы (2)


Похоже, вы извлекли все Foos, все FooInfo и все Bars из базы данных, чтобы вы могли выполнить запрос, в результате которого вам действительно нужен только один объект Bar. Если вам все равно нужно было получить все эти объекты из базы данных для другого запроса, то это нормально, но если вы получили все эти объекты только для этого одного запроса, то это крайне неэффективно. Вы должны попытаться заставить базу данных выполнить запрос и вернуть только один объект, который вам нужен.

Даже если ограничений по внешнему ключу нет, вы все равно можете выполнять соединения, а также установить отношения между типами в Linq To SQL, даже если они фактически не существуют в базе данных, что упрощает формулирование ваших запросов.

person Mark Byers    schedule 05.12.2009

Может быть сложно стилистически принять соединения, которые использует синтаксис Lambda. Синтаксис обработки запросов имеет гораздо лучший стиль для объединения. Выполняются те же операции.

Bar conflicting = 
(
  from foo in allFoos
  where foo.ElectronicSerialNumber != 0
  where foo.BarID != interestingBar.ID
  join fooInfo in fooInfoCollection
  on foo.ElectronicSerialNumber equals fooInfo.ElectronicID
  join bar in allBars
  on foo.BarID equals bar.ID
  where !bar.SomeCriteria
  select bar
).FirstOrDefault();

Обратите внимание, что foo и fooInfo (и bar) находятся в области действия предложения select, если вы хотите их использовать.

person Amy B    schedule 06.12.2009