LINQ to SQL: несколько соединений в нескольких Столбцах. Это возможно?
дано:
таблицы со следующими столбцами:
IDColumnAColumnBColumnC
у меня есть SQL-запрос, где TABLE_1 присоединяется к себе дважды на основеColumnA,ColumnB,ColumnC. Запрос может выглядеть примерно так:
Select t1.ID, t2.ID, t3.ID
From TABLE_1 t1
Left Join TABLE_1 t2 On
t1.ColumnA = t2.ColumnA
And t1.ColumnB = t2.ColumnB
And t1.ColumnC = t2.ColumnC
Left Join TABLE_1 t3 On
t2.ColumnA = t3.ColumnA
And t2.ColumnB = t3.ColumnB
And t2.ColumnC = t3.ColumnC
... and query continues on etc.
:
мне нужно, чтобы этот запрос был переписано в LINQ. Я попытался взять удар на него:
var query =
from t1 in myTABLE1List // List<TABLE_1>
join t2 in myTABLE1List
on t1.ColumnA equals t2.ColumnA
&& t1.ColumnB equals t2.ColumnA
// ... and at this point intellisense is making it very obvious
// I am doing something wrong :(
Как написать мой запрос в LINQ? Что я делаю не так?
8 ответов:
объединение нескольких столбцов в Linq to SQL немного отличается.
var query = from t1 in myTABLE1List // List<TABLE_1> join t2 in myTABLE1List on new { t1.ColumnA, t1.ColumnB } equals new { t2.ColumnA, t2.ColumnB } ...вы должны воспользоваться анонимными типами и составить тип для нескольких столбцов, с которыми вы хотите сравнить.
сначала это кажется запутанным, но как только вы познакомитесь с тем, как SQL состоит из выражений, это будет иметь гораздо больше смысла, под обложками это создаст тип соединения, который вы ищете.
EDIT Добавление примера для второго соединения на основе комментария.
var query = from t1 in myTABLE1List // List<TABLE_1> join t2 in myTABLE1List on new { A = t1.ColumnA, B = t1.ColumnB } equals new { A = t2.ColumnA, B = t2.ColumnB } join t3 in myTABLE1List on new { A = t2.ColumnA, B = t2.ColumnB } equals new { A = t3.ColumnA, B = t3.ColumnB } ...
в LINQ2SQL вам редко нужно явно присоединяться при использовании внутренних соединений.
Если у вас есть правильные отношения внешнего ключа в вашей базе данных, вы автоматически получите отношение в конструкторе LINQ (если нет, вы можете создать отношение вручную в конструкторе, хотя у вас действительно должны быть правильные отношения в вашей базе данных)
тогда вы можете просто получить доступ к связанным таблицам с помощью "точечной нотации"
var q = from child in context.Childs where child.Parent.col2 == 4 select new { childCol1 = child.col1, parentCol1 = child.Parent.col1, };будет генерировать запрос
SELECT [t0].[col1] AS [childCol1], [t1].[col1] AS [parentCol1] FROM [dbo].[Child] AS [t0] INNER JOIN [dbo].[Parent] AS [t1] ON ([t1].[col1] = [t0].[col1]) AND ([t1].[col2] = [t0].[col2]) WHERE [t1].[col2] = @p0 -- @p0: Input Int (Size = -1; Prec = 0; Scale = 0) [4] -- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 4.0.30319.1на мой взгляд, это гораздо более читабельно и позволяет сосредоточиться на ваших особых условиях, а не на реальной механике соединения.
Edit
Это, конечно, применимо только тогда, когда вы хотите присоединиться к нашей модели базы данных. Если вы хотите присоединиться "вне модели", вам нужно прибегнуть к ручным соединениям, как в ответ С Кинтин Робинзон
Title_Authors-это поиск двух вещей, которые объединяют одновременно результаты проекта и продолжают цепочку
DataClasses1DataContext db = new DataClasses1DataContext(); var queryresults = from a in db.Authors join ba in db.Title_Authors on a.Au_ID equals ba.Au_ID into idAuthor from c in idAuthor join t in db.Titles on c.ISBN equals t.ISBN select new { Author = a.Author1,Title= t.Title1 }; foreach (var item in queryresults) { MessageBox.Show(item.Author); MessageBox.Show(item.Title); return; }
U также можете использовать :
var query = from t1 in myTABLE1List join t2 in myTABLE1List on new { ColA=t1.ColumnA, ColB=t1.ColumnB } equals new { ColA=t2.ColumnA, ColB=t2.ColumnB } join t3 in myTABLE1List on new {ColC=t2.ColumnA, ColD=t2.ColumnB } equals new { ColC=t3.ColumnA, ColD=t3.ColumnB }
Я хотел бы привести еще один пример, в котором используется несколько (3) соединений.
DataClasses1DataContext ctx = new DataClasses1DataContext(); var Owners = ctx.OwnerMasters; var Category = ctx.CategoryMasters; var Status = ctx.StatusMasters; var Tasks = ctx.TaskMasters; var xyz = from t in Tasks join c in Category on t.TaskCategory equals c.CategoryID join s in Status on t.TaskStatus equals s.StatusID join o in Owners on t.TaskOwner equals o.OwnerID select new { t.TaskID, t.TaskShortDescription, c.CategoryName, s.StatusName, o.OwnerName };
вы также можете присоединиться, если количество столбцов не совпадает в обеих таблицах и может сопоставить статическое значение столбцу таблицы
from t1 in Table1 join t2 in Table2 on new {X = t1.Column1, Y = 0 } on new {X = t2.Column1, Y = t2.Column2 } select new {t1, t2}
на мой взгляд, это самый простой способ объединить две таблицы с несколькими полями:
from a in Table1 join b in Table2 on (a.Field1.ToString() + "&" + a.Field2.ToString()) equals (b.Field1.ToString() + "&" + b.Field2.ToString()) select a
вы можете написать свой запрос следующим образом.
var query = from t1 in myTABLE1List // List<TABLE_1> join t2 in myTABLE1List on t1.ColumnA equals t2.ColumnA and t1.ColumnB equals t2.ColumnAЕсли вы хотите сравнить колонки с несколькими столбцами.

Comments