Quelle est la syntaxe d'une jointure interne dans LINQ to SQL?

443

J'écris une instruction LINQ to SQL, et je suis après la syntaxe standard pour une jointure interne normale avec une ONclause en C #.

Comment représentez-vous les éléments suivants dans LINQ to SQL:

select DealerContact.*
from Dealer 
inner join DealerContact on Dealer.DealerID = DealerContact.DealerID
Glenn Slaven
la source
Si vous avez une clé étrangère entre les tables, vous devriez regarder la réponse de Kirk Broadhurst ci-dessous.
Guilherme
1
Vous devez pluraliser les noms de vos tables. Une table contenant (entrées sur) de nombreux concessionnaires doit être appelée concessionnaire et non concessionnaire.
ANeves
5
@ANeves Il est loin d'être une pratique courante d'utiliser des noms de table au pluriel, le singulier et le pluriel sont parfaitement acceptables - je viens de passer du pluriel au singulier moi-même pour faire correspondre les noms des objets - ici, la première réponse convient que le singulier est plus cohérent (de nombreuses pluralisations sont étranges ou non existant - par exemple «1 mouton, 8 moutons»: stackoverflow.com/questions/338156/…
niico
@niico ce n'est pas l'endroit pour en discuter, je suppose ... mais Microsoft Entity Framework pluralise les noms des tables , l'ORM de Ruby on Rails pluralise les tables ... est-ce assez proche de la pratique standard pour vous? :) Contre-argument: NHibernate ne semble pas pluraliser les tableaux .
ANeves
2
En effet - certaines personnes le font d'une manière - d'autres le font d'une autre manière. Il n'y a pas de pratique standard. Personnellement, je pense que le singulier a bien plus d'avantages.
niico

Réponses:

572

Cela va quelque chose comme:

from t1 in db.Table1
join t2 in db.Table2 on t1.field equals t2.field
select new { t1.field2, t2.field3}

Ce serait bien d'avoir des noms et des champs raisonnables pour vos tables pour un meilleur exemple. :)

Mise à jour

Je pense que pour votre requête, cela pourrait être plus approprié:

var dealercontacts = from contact in DealerContact
                     join dealer in Dealer on contact.DealerId equals dealer.ID
                     select contact;

Puisque vous recherchez les contacts, pas les revendeurs.

Jon Limjap
la source
11
merci, à partir de maintenant j'utiliserai des noms sensés comme meilleure pratique qui a du sens dans linq, au lieu defrom c or from t1
shaijut
231

Et parce que je préfère la syntaxe de la chaîne d'expression, voici comment vous le faites:

var dealerContracts = DealerContact.Join(Dealer, 
                                 contact => contact.DealerId,
                                 dealer => dealer.DealerId,
                                 (contact, dealer) => contact);
CleverPatrick
la source
8
Si vous devez filtrer ou sélectionner sur les champs des deux tables jointes, au lieu de simplement sur les champs de l'une des deux tables (la table DealerContact dans l'exemple de cette réponse), voici un exemple: stackoverflow.com/a/29310640/12484
Jon Schneider
52

Pour étendre la réponse de la syntaxe de la chaîne d'expression par Clever Human:

Si vous vouliez faire des choses (comme filtrer ou sélectionner) sur les champs des deux tables jointes - au lieu d'une seule de ces deux tables - vous pourriez créer un nouvel objet dans l'expression lambda du paramètre final de la méthode Join incorporant ces deux tableaux, par exemple:

var dealerInfo = DealerContact.Join(Dealer, 
                              dc => dc.DealerId,
                              d => d.DealerId,
                              (dc, d) => new { DealerContact = dc, Dealer = d })
                          .Where(dc_d => dc_d.Dealer.FirstName == "Glenn" 
                              && dc_d.DealerContact.City == "Chicago")
                          .Select(dc_d => new {
                              dc_d.Dealer.DealerID,
                              dc_d.Dealer.FirstName,
                              dc_d.Dealer.LastName,
                              dc_d.DealerContact.City,
                              dc_d.DealerContact.State });

La partie intéressante est l'expression lambda à la ligne 4 de cet exemple:

(dc, d) => new { DealerContact = dc, Dealer = d }

... où nous construisons un nouvel objet de type anonyme qui a pour propriétés les enregistrements DealerContact et Dealer, ainsi que tous leurs champs.

Nous pouvons ensuite utiliser les champs de ces enregistrements pendant que nous filtrons et sélectionnons les résultats, comme le montre le reste de l'exemple, qui utilise dc_dcomme nom pour l'objet anonyme que nous avons construit qui a à la fois les enregistrements DealerContact et Dealer comme propriétés.

Jon Schneider
la source
9
Les jointures avec lambdas ont une syntaxe affreuse. Je refuse de l'utiliser ;-)
Mariusz
12
@aristo Je ne te blâme pas du tout. Je dois généralement me référer à ce post pour me rappeler la syntaxe!
Jon Schneider
2
Certaines personnes comme moi préfèrent la cohérence. C'est pourquoi je recherche spécifiquement la syntaxe lambda.
0014
43
var results = from c in db.Companies
              join cn in db.Countries on c.CountryID equals cn.ID
              join ct in db.Cities on c.CityID equals ct.ID
              join sect in db.Sectors on c.SectorID equals sect.ID
              where (c.CountryID == cn.ID) && (c.CityID == ct.ID) && (c.SectorID == company.SectorID) && (company.SectorID == sect.ID)
              select new { country = cn.Name, city = ct.Name, c.ID, c.Name, c.Address1, c.Address2, c.Address3, c.CountryID, c.CityID, c.Region, c.PostCode, c.Telephone, c.Website, c.SectorID, Status = (ContactStatus)c.StatusID, sector = sect.Name };


return results.ToList();
Herste
la source
1
Salut, pouvez-vous me dire de quoi il s'agit dans cette partie? Status = (ContactStatus) c.StatusID Je m'intéresse particulièrement au fragment: (ContactStatus) c.StatusID Cordialement Mariusz
Mariusz
1
@aristo - en regardant le code, je suppose que ContactStatusc'est vraiment une énumération, et ce c.StatusIDn'est pas vraiment un ID, mais la valeur numérique de l'énumération. Si je ne me trompe pas, il (ContactStatus)c.StatusIDs'agit simplement de convertir un entier en une énumération.
Joel Mueller
25

Utilisez l' opérateur Linq Join :

var q =  from d in Dealer
         join dc in DealerConact on d.DealerID equals dc.DealerID
         select dc;
aku
la source
1
que faire quand je veux des colonnes à la fois d & dc?
Kuntady Nithesh
1
@KuntadyNithesh Puis retournez une classe que vous avez créée comme sélectionnez un nouveau MyCustomer {Id = dc.id, Id2 = d.id} C'est tout!
Elisabeth
25

Vous créez une clé étrangère et LINQ-to-SQL crée des propriétés de navigation pour vous. Chacun Dealeraura alors une collection DealerContactsdont vous pourrez sélectionner, filtrer et manipuler.

from contact in dealer.DealerContacts select contact

ou

context.Dealers.Select(d => d.DealerContacts)

Si vous n'utilisez pas les propriétés de navigation, vous manquez l'un des principaux avantages de LINQ-to-SQL - la partie qui mappe le graphique d'objet.

Kirk Broadhurst
la source
Oh mec, tu m'as fait gagner du temps, je n'ai plus besoin de faire face à ces stupides jointures!
Tomas
23

fondamentalement, l' opérateur de jointure LINQ n'offre aucun avantage pour SQL. C'est-à-dire la requête suivante

var r = from dealer in db.Dealers
   from contact in db.DealerContact
   where dealer.DealerID == contact.DealerID
   select dealerContact;

entraînera INNER JOIN en SQL

join est utile pour IEnumerable <> car il est plus efficace:

from contact in db.DealerContact  

serait réexécutée pour chaque revendeur Mais pour IQueryable <> ce n'est pas le cas. Aussi adhésion est également moins flexible.

the_joric
la source
12

En fait, il vaut souvent mieux ne pas adhérer, en linq c'est-à-dire. Lorsqu'il existe des propriétés de navigation, un moyen très succinct d'écrire votre instruction linq est:

from dealer in db.Dealers
from contact in dealer.DealerContacts
select new { whatever you need from dealer or contact }

Cela se traduit par une clause where:

SELECT <columns>
FROM Dealer, DealerContact
WHERE Dealer.DealerID = DealerContact.DealerID
Gert Arnold
la source
À quoi ressemble une requête LINQ avec plusieurs clauses "from" (comme dans cet exemple) dans la syntaxe de la chaîne d'expression? C'est possible?
Jon Schneider
1
Son équivalent de syntaxe de méthode est SelectMany().
Gert Arnold
3

Utilisez les jointures LINQ pour effectuer la jointure interne.

var employeeInfo = from emp in db.Employees
                   join dept in db.Departments
                   on emp.Eid equals dept.Eid 
                   select new
                   {
                    emp.Ename,
                    dept.Dname,
                    emp.Elocation
                   };
Uthaiah
la source
3

Essaye ça :

     var data =(from t1 in dataContext.Table1 join 
                 t2 in dataContext.Table2 on 
                 t1.field equals t2.field 
                 orderby t1.Id select t1).ToList(); 
Ajay
la source
3
var q=(from pd in dataContext.tblProducts join od in dataContext.tblOrders on pd.ProductID equals od.ProductID orderby od.OrderID select new { od.OrderID,
 pd.ProductID,
 pd.Name,
 pd.UnitPrice,
 od.Quantity,
 od.Price,
 }).ToList(); 
ammad khan
la source
Bienvenue dans Stack Overflow! Bien que cet extrait de code puisse résoudre la question, y compris une explication aide vraiment à améliorer la qualité de votre message. N'oubliez pas que vous répondrez à la question pour les lecteurs à l'avenir, et ces personnes pourraient ne pas connaître les raisons de votre suggestion de code. Essayez également de ne pas surcharger votre code avec des commentaires explicatifs, car cela réduit la lisibilité du code et des explications!
Au revoir StackExchange
2
OperationDataContext odDataContext = new OperationDataContext();    
        var studentInfo = from student in odDataContext.STUDENTs
                          join course in odDataContext.COURSEs
                          on student.course_id equals course.course_id
                          select new { student.student_name, student.student_city, course.course_name, course.course_desc };

Où les tables des étudiants et des cours ont une relation clé primaire et clé étrangère

Sandeep Shekhawat
la source
2

essayez plutôt ceci,

var dealer = from d in Dealer
             join dc in DealerContact on d.DealerID equals dc.DealerID
             select d;
Milan
la source
1
var Data= (from dealer in Dealer join dealercontact in DealerContact on dealer.ID equals dealercontact.DealerID
select new{
dealer.Id,
dealercontact.ContactName

}).ToList();
Ankita_systematix
la source
1
var data=(from t in db.your tableName(t1) 
          join s in db.yourothertablename(t2) on t1.fieldname equals t2.feldname
          (where condtion)).tolist();
sanket parikh
la source
1
var list = (from u in db.Users join c in db.Customers on u.CustomerId equals c.CustomerId where u.Username == username
   select new {u.UserId, u.CustomerId, u.ClientId, u.RoleId, u.Username, u.Email, u.Password, u.Salt, u.Hint1, u.Hint2, u.Hint3, u.Locked, u.Active,c.ProfilePic}).First();

Écrivez les noms de table souhaités et initialisez la sélection pour obtenir le résultat des champs.

Sarfraj Sutar
la source
var list = (from u in db.Yourfirsttablename join c in db.secondtablename on u.firsttablecommonfields equals c.secondtablecommon field where u.Username == username select new {u.UserId, u.CustomerId, u.ClientId, u.RoleId , u.Username, u.Email, u.Password, u.Salt, u.Hint1, u.Hint2, u.Hint3, u.Locked, u.Active, c.ProfilePic}). First ();
Sarfraj Sutar
1

Jointure interne de deux tables en linq C #

var result = from q1 in table1
             join q2 in table2
             on q1.Customer_Id equals q2.Customer_Id
             select new { q1.Name, q1.Mobile, q2.Purchase, q2.Dates }
Md Shahriar
la source
1

de d1 dans DealerContrac rejoindre d2 dans DealerContrac sur d1.dealearid est égal à d2.dealerid sélectionnez nouveau {dealercontract. *}

Rutu
la source
Bienvenue dans Stack Overflow! Cette réponse n'ajoute rien aux réponses déjà existantes.
Jeroen Heier
-6

Un meilleur exemple

Noms de table: TBL_EmpetTBL_Dep

var result = from emp in TBL_Emp join dep in TBL_Dep on emp.id=dep.id
select new
{
 emp.Name;
 emp.Address
 dep.Department_Name
}


foreach(char item in result)
 { // to do}
Prasad KM
la source