Question

Je travaille avec la requête SQL suivante:

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

Je ne sais pas comment atteindre les JOIN dans LINQ. Toutes mes tables ont des relations de clé étrangère.

Était-ce utile?

La solution

Vous devrez peut-être modifier cela légèrement au fur et à mesure que je partais à l'improviste, mais vous devez garder à l'esprit certains points importants. Si vos relations sont correctement configurées dans votre fichier dbml, vous devriez être en mesure de faire des jointures internes de manière implicite et d'accéder simplement aux données via votre table initiale. De plus, les jointures de gauche dans LINQ ne sont pas aussi simples qu'on pourrait l'espérer et vous devez suivre la syntaxe DefaultIfEmpty pour que cela se produise. J'ai créé un type anonyme ici, mais vous souhaiterez peut-être utiliser une classe DTO ou quelque chose de similaire. Je ne savais pas non plus ce que vous vouliez faire dans le cas des valeurs NULL, mais vous pouvez utiliser le code ?? syntaxe pour définir une valeur à donner à la variable si la valeur est null. Faites-moi savoir si vous avez des questions supplémentaires ...

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);

Autres conseils

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

Cet appel à la méthode linq (to Join) générera la jointure ci-dessus.

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

Ces appels de méthode linq (à GroupJoin, SelectMany, DefaultIfEmpty) produiront la jointure gauche ci-dessus

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.
);

Le concept clé est que les méthodes de Linq produisent des résultats structurés hiérarchiquement et non des formes ligne-colonne aplaties.

  • Le GroupBy de Linq produit des résultats mis en forme dans une hiérarchie avec une clé de regroupement correspondant à une collection d'éléments (qui peuvent ne pas être vides). La clause GroupBy de SQL génère une clé de regroupement avec des valeurs agrégées - il n'y a pas de sous-collection avec laquelle travailler.
  • De même, GroupJoin de Linq génère une forme hiérarchique - un enregistrement parent correspondant à une collection d'enregistrements enfants (qui peut être vide). Le code LEFT JOIN de Sql produit un enregistrement parent correspondant à chaque enregistrement enfant ou un enregistrement enfant null s'il n'y a pas d'autres correspondances. Pour obtenir la forme de Sql à partir de la forme de Linq, vous devez décompresser la collection d'enregistrements enfants avec SelectMany - et gérer les collections vides d'enregistrements enfants à l'aide de DefaultIfEmpty .

Et voici ma tentative de linquifier ce SQL dans la question:

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 vous souhaitez conserver les astuces (NOLOCK), j'ai a blogué une solution pratique utilisant des méthodes d’extension en C #. Notez que cela revient à ajouter des astuces nolock à chaque table de la requête.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top