Эквивалентен ли этот запрос LEFT OUTER
соединению?
//assuming that I have a parameter named 'invoiceId' of type int
from c in SupportCases
let invoice = c.Invoices.FirstOrDefault(i=> i.Id == invoiceId)
where (invoiceId == 0 || invoice != null)
select new
{
Id = c.Id
, InvoiceId = invoice == null ? 0 : invoice.Id
}
.net
database
linq
linq-to-sql
Али Казми
источник
источник
Вам не нужны операторы в:
var query = from customer in dc.Customers from order in dc.Orders .Where(o => customer.CustomerId == o.CustomerId) .DefaultIfEmpty() select new { Customer = customer, Order = order } //Order will be null if the left join is null
И да, приведенный выше запрос действительно создает соединение LEFT OUTER.
Ссылка на аналогичный вопрос, который обрабатывает несколько левых соединений: Linq to Sql: несколько левых внешних соединений
источник
Public Sub LinqToSqlJoin07() Dim q = From e In db.Employees _ Group Join o In db.Orders On e Equals o.Employee Into ords = Group _ From o In ords.DefaultIfEmpty _ Select New With {e.FirstName, e.LastName, .Order = o} ObjectDumper.Write(q) End Sub
Проверьте http://msdn.microsoft.com/en-us/vbasic/bb737929.aspx
источник
Я нашел 1 решение. если вы хотите перевести этот тип SQL (левое соединение) в Linq Entity ...
SQL:
SELECT * FROM [JOBBOOKING] AS [t0] LEFT OUTER JOIN [REFTABLE] AS [t1] ON ([t0].[trxtype] = [t1].[code]) AND ([t1]. [reftype] = "TRX")
LINQ:
from job in JOBBOOKINGs join r in (from r1 in REFTABLEs where r1.Reftype=="TRX" select r1) on job.Trxtype equals r.Code into join1 from j in join1.DefaultIfEmpty() select new { //cols... }
источник
DefaultIfEmpty
.Хочу добавить еще кое-что. В LINQ to SQL, если ваша БД правильно построена и ваши таблицы связаны через ограничения внешнего ключа, вам вообще не нужно выполнять соединение.
Используя LINQPad, я создал следующий запрос LINQ:
//Querying from both the CustomerInfo table and OrderInfo table from cust in CustomerInfo where cust.CustomerID == 123456 select new {cust, cust.OrderInfo}
Что было переведено в (слегка усеченный) запрос ниже
-- Region Parameters DECLARE @p0 Int = 123456 -- EndRegion SELECT [t0].[CustomerID], [t0].[AlternateCustomerID], [t1].[OrderID], [t1].[OnlineOrderID], ( SELECT COUNT(*) FROM [OrderInfo] AS [t2] WHERE [t2].[CustomerID] = [t0].[CustomerID] ) AS [value] FROM [CustomerInfo] AS [t0] LEFT OUTER JOIN [OrderInfo] AS [t1] ON [t1].[CustomerID] = [t0].[CustomerID] WHERE [t0].[CustomerID] = @p0 ORDER BY [t0].[CustomerID], [t1].[OrderID]
Обратите внимание на
LEFT OUTER JOIN
вышеизложенное.источник
Позаботьтесь о производительности:
Я испытал, что, по крайней мере, с EF Core разные ответы, приведенные здесь, могут привести к разной производительности. Мне известно, что OP спрашивал о Linq to SQL, но мне кажется, что те же вопросы возникают и с EF Core.
В конкретном случае, с которым мне пришлось справиться, (синтаксически более приятное) предложение Марка Гравелла привело к левым соединениям внутри перекрестного применения - аналогично тому, что описал Майк У. - в результате чего предполагаемые затраты на этот конкретный запрос составили два в разы выше по сравнению с запросом без перекрестных соединений . Время выполнения сервера отличалось в 3 раза . [1]
Решение Марка Гравелла привело к запросу без перекрестных соединений.
Контекст: мне, по сути, нужно было выполнить два левых соединения для двух таблиц, каждая из которых снова требовала соединения с другой таблицей. Кроме того, там мне пришлось указать другие условия для таблиц, к которым мне нужно было применить левое соединение. Вдобавок у меня было два внутренних соединения на главной таблице.
Ориентировочные расходы оператора:
Время выполнения сервером в мс (запросы выполнялись 10 раз; измерено с помощью SET STATISTICS TIME ON):
(Самый первый запуск был медленнее для обоих запросов; кажется, что что-то кешируется.)
Размеры стола:
Версия EF Core: 2.2.1.
Версия SQL Server: MS SQL Server 2017-14 ... (в Windows 10).
Все соответствующие таблицы имели индексы только по первичным ключам.
Мой вывод: всегда рекомендуется смотреть на сгенерированный SQL, поскольку он действительно может отличаться.
[1] Интересно, что при включении «Клиентской статистики» в MS SQL Server Management Studio я мог увидеть противоположную тенденцию; а именно, последний запуск решения без перекрестного применения занял более 1 секунды. Полагаю, что здесь что-то пошло не так - может быть, с моей настройкой.
источник