LINQ to SQL: Múltiples uniones EN múltiples columnas. Es esto posible?
Dado:
Una tabla llamada TABLE_1
con las siguientes columnas:
ID
ColumnA
ColumnB
ColumnC
Tengo una consulta SQL donde TABLE_1
se une a sí misma dos veces basada en ColumnA
, ColumnB
, ColumnC
. La consulta podría ser algo como esto:
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.
Problema:
Necesito que esa consulta se reescriba en LINQ. He intentado apuñalarlo:
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 :(
¿Cómo escribo mi consulta en LINQ? ¿Qué estoy haciendo mal?
8 answers
Unir varias columnas en Linq a SQL es un poco diferente.
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 }
...
Debe aprovechar los tipos anónimos y componer un tipo para las múltiples columnas con las que desea comparar.
Esto parece confuso al principio, pero una vez que se familiarice con la forma en que se compone el SQL a partir de las expresiones, tendrá mucho más sentido, bajo las portadas esto generará el tipo de unión que está buscando.
EDIT Añadiendo ejemplo para la segunda unión basado en el comentario.
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 }
...
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-24 07:01:48
En LINQ2SQL rara vez necesita unirse explícitamente cuando usa uniones internas.
Si tiene relaciones de clave foránea adecuadas en su base de datos obtendrá automáticamente una relación en el diseñador LINQ (si no, puede crear una relación manualmente en el diseñador, aunque realmente debería tener relaciones adecuadas en su base de datos)
Entonces solo puede acceder a las tablas relacionadas con la"notación de puntos"
var q = from child in context.Childs
where child.Parent.col2 == 4
select new
{
childCol1 = child.col1,
parentCol1 = child.Parent.col1,
};
Generará la consulta
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
En mi opinión esto es mucho más legible y le permite concentrarse en sus condiciones especiales y no en la mecánica real de la unión.
Editar
Por supuesto, esto solo es aplicable cuando desea unirse a la línea con nuestro modelo de base de datos. Si desea unirse "fuera del modelo", debe recurrir a las uniones manuales como en la respuesta de Quintin Robinson
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:26:20
Title_Authors es una búsqueda de dos cosas unir a la vez los resultados del proyecto y continuar encadenando
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;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-07-13 05:14:03
U también puede usar:
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 }
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-21 14:09:01
Me gustaría dar otro ejemplo en el que se usan múltiples (3) uniones.
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
};
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-07 03:08:15
También puede unirse si el número de columnas no es el mismo en ambas tablas y puede asignar valor estático a la columna de tabla
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}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-02 08:00:20
En mi opinión, esta es la forma más sencilla de unir dos tablas con múltiples campos:
from a in Table1 join b in Table2
on (a.Field1.ToString() + "&" + a.Field2.ToString())
equals (b.Field1.ToString() + "&" + b.Field2.ToString())
select a
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-09-21 08:37:09
Puede escribir su consulta de esta manera.
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
Si desea comparar su columna con varias columnas.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-03-15 05:39:47