Pregunta

Estoy trabajando con la siguiente consulta SQL:

SELECT 
a.AppointmentId,
a.Status,
a.Type,
a.Title,
b.Days,
d.Description,
e.FormId
FROM Appointment a (nolock)
LEFT JOIN AppointmentFormula b (nolock)
ON a.AppointmentId = b.AppointmentId and b.RowStatus = 1
JOIN Type d (nolock)
ON a.Type = d.TypeId
LEFT JOIN AppointmentForm e (nolock)
ON e.AppointmentId = a.AppointmentId
WHERE a.RowStatus = 1
AND a.Type = 1
ORDER BY a.Type

No estoy seguro de cómo lograr las UNIONES en LINQ. Todas mis tablas tienen relaciones de claves externas.

¿Fue útil?

Solución

Es posible que tenga que ajustar esto ligeramente cuando me estaba saliendo del manguito, pero hay un par de cosas importantes a tener en cuenta. Si tiene sus relaciones configuradas correctamente en su dbml, debería poder hacer uniones internas implícitamente y simplemente acceder a los datos a través de su tabla inicial. Además, las uniones izquierdas en LINQ no son tan sencillas como podríamos esperar y debe pasar por la sintaxis DefaultIfEmpty para que esto suceda. Creé un tipo anónimo aquí, pero es posible que desee colocar en una clase DTO o algo por el estilo. Tampoco sabía lo que quería hacer en el caso de nulos, pero puede usar el ?? sintaxis para definir un valor para dar la variable si el valor es nulo. Avíseme si tiene preguntas adicionales ...

var query = (from a in context.Appointment
join b in context.AppointmentFormula on a.AppointmentId equals b.AppointmentId into temp
from c in temp.DefaultIfEmpty()
join d in context.AppointmentForm on a.AppointmentID equals e.AppointmentID into temp2
from e in temp2.DefaultIfEmpty()
where a.RowStatus == 1 && c.RowStatus == 1 && a.Type == 1
select new {a.AppointmentId, a.Status, a.Type, a.Title, c.Days ?? 0, a.Type.Description, e.FormID ?? 0}).OrderBy(a.Type);

Otros consejos

SELECT A.X, B.Y
FROM A JOIN B ON A.X = B.Y

Esta llamada al método linq (para unirse) generará la combinación anterior.

var query = A.Join
(
  B,
  a => a.x,
  b => b.y,
  (a, b) => new {a.x, b.y} //if you want more columns - add them here.
);

SELECT A.X, B.Y
FROM A LEFT JOIN B ON A.X = B.Y

Estas llamadas al método linq (a GroupJoin, SelectMany, DefaultIfEmpty) producirán la combinación Left Left anterior

var query = A.GroupJoin
(
  B,
  a => a.x,
  b => b.y,
  (a, g) => new {a, g}
).SelectMany
(
  z => z.g.DefaultIfEmpty(),
  (z, b) =>
    new  { x = z.a.x, y = b.y } //if you want more columns - add them here.
);

El concepto clave aquí es que los métodos de Linq producen resultados con formas jerárquicas, no formas planas de fila-columna.

  • El GroupBy de Linq produce resultados formados en una jerarquía con una clave de agrupación asociada a una colección de elementos (que pueden no estar vacíos). La cláusula GroupBy de SQL produce una clave de agrupación con valores agregados : no hay una subcolección con la que trabajar.
  • Del mismo modo, el GroupJoin de Linq produce una forma jerárquica: un registro primario que coincide con una colección de registros secundarios (que pueden estar vacíos). El LEFT JOIN de SQL produce un registro padre que coincide con cada registro hijo, o un registro hijo nulo si no hay otras coincidencias. Para llegar a la forma de Sql desde la forma de Linq, uno debe desempaquetar la colección de registros secundarios con SelectMany - y manejar las colecciones vacías de registros secundarios usando DefaultIfEmpty .

Y aquí está mi intento de linquificar ese sql en la pregunta:

var query =
  from a in Appointment
  where a.RowStatus == 1
  where a.Type == 1
  from b in a.AppointmentFormula.Where(af => af.RowStatus == 1).DefaultIfEmpty()
  from d in a.TypeRecord //a has a type column and is related to a table named type, disambiguate the names
  from e in a.AppointmentForm.DefaultIfEmpty()
  order by a.Type
  select new { a.AppointmentId, a.Status, a.Type, a.Title, b.Days, d.Description, e.Form }

Si desea preservar las sugerencias (NOLOCK), tengo blogueó una solución práctica utilizando métodos de extensión en C #. Tenga en cuenta que esto es lo mismo que agregar sugerencias nolock a cada tabla en la consulta.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top