Qual è la sintassi per un join interno in LINQ to SQL?


443

Sto scrivendo un'istruzione LINQ to SQL e sto seguendo la sintassi standard per un normale join interno con una ONclausola in C #.

Come si rappresentano i seguenti elementi in LINQ to SQL:

select DealerContact.*
from Dealer 
inner join DealerContact on Dealer.DealerID = DealerContact.DealerID

Se hai una chiave esterna tra i tavoli, dovresti cercare la risposta di Kirk Broadhurst di seguito.
Guilherme,

1
Dovresti pluralizzare i nomi delle tue tabelle. Una tabella che contiene (voci su) molti rivenditori dovrebbe essere chiamata rivenditori , e non rivenditore.
ANeves

5
@ANeves È lontano dalla pratica standard usare nomi di tabelle plurali, sia singolari che plurali sono perfettamente accettabili - Sono appena passato dal plurale al singolare me stesso per abbinare i nomi degli oggetti - qui la risposta superiore concorda singolare è più coerente (molte pluralizzazioni sono strane o non esistenti - ad esempio '1 pecora, pecore 8': stackoverflow.com/questions/338156/...
Niico

@niico questo non è il posto giusto per discuterne, immagino ... ma Microsoft Entity Framework pluralizza i nomi delle tabelle , l'ORM di Ruby on Rails pluralizza le tabelle ... è abbastanza vicino alla pratica standard per te? :) Contro-argomento: NHibernate sembra non pluralizzare le tabelle .
ANeves,

2
In effetti - alcune persone lo fanno in un modo - altri lo fanno in un altro modo. Non esiste una pratica standard. Personalmente penso che singolare abbia molti più benefici.
Niico,

Risposte:


572

Va qualcosa come:

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

Sarebbe bello avere nomi e campi sensibili per le tue tabelle per un esempio migliore. :)

Aggiornare

Penso che per la tua domanda questo potrebbe essere più appropriato:

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

Dal momento che stai cercando i contatti, non i rivenditori.


11
grazie, d'ora in poi userò nomi sensibili come best practice che ha senso in linq, invece difrom c or from t1
shaijut

231

E poiché preferisco la sintassi della catena di espressioni, ecco come lo fai:

var dealerContracts = DealerContact.Join(Dealer, 
                                 contact => contact.DealerId,
                                 dealer => dealer.DealerId,
                                 (contact, dealer) => contact);

8
Se è necessario filtrare o selezionare i campi da entrambe le tabelle unite, anziché solo i campi di una delle due tabelle (la tabella DealerContact nell'esempio di questa risposta), ecco un esempio: stackoverflow.com/a/29310640/12484
Jon Schneider,

52

Per estendere la risposta della sintassi della catena di espressioni di Clever Human:

Se volessi fare cose (come filtrare o selezionare) sui campi di entrambe le tabelle che vengono unite insieme - invece su una sola di quelle due tabelle - potresti creare un nuovo oggetto nell'espressione lambda del parametro finale al metodo Join incorporando entrambe queste tabelle, ad esempio:

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 parte interessante è l'espressione lambda nella riga 4 di quell'esempio:

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

... dove costruiamo un nuovo oggetto di tipo anonimo che ha come proprietà i record DealerContact e Dealer, insieme a tutti i loro campi.

Possiamo quindi utilizzare i campi di tali record mentre filtriamo e selezioniamo i risultati, come dimostrato dal resto dell'esempio, che utilizza dc_dcome nome l'oggetto anonimo che abbiamo creato che ha sia i record DealerContact che i record Dealer come proprietà.


9
I join con lambda hanno una sintassi terribile. Mi rifiuto di usarlo ;-)
Mariusz,

12
@aristo Non ti biasimo affatto. Di solito devo fare riferimento a questo post per ricordare a me stesso la sintassi!
Jon Schneider,

2
Alcune persone come me preferiscono la coerenza. Ecco perché cerco specificamente la sintassi 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();

1
Ciao, puoi dirmi per favore di cosa tratta questa parte? Status = (ContactStatus) c.StatusID Sono interessato in particolare al frammento: (ContactStatus) c.StatusID Saluti Mariusz
Mariusz

1
@aristo - guardando il codice, immagino che ContactStatussia davvero un enum e c.StatusIDnon sia un ID, ma il valore numerico dell'enum. Se ho ragione, (ContactStatus)c.StatusIDsta semplicemente lanciando un numero intero in un enum.
Joel Mueller,

25

Utilizza l' operatore Linq Join :

var q =  from d in Dealer
         join dc in DealerConact on d.DealerID equals dc.DealerID
         select dc;

1
cosa fare quando voglio colonne di entrambi d & dc?
Kuntady Nithesh,

1
@KuntadyNithesh Quindi restituisci una classe che hai creato come seleziona new MyCustomer {Id = dc.id, Id2 = d.id} Ecco fatto!
Elisabeth,

25

Si crea una chiave esterna e LINQ-to-SQL crea le proprietà di navigazione per te. Ciascuno Dealeravrà quindi una raccolta di DealerContactscui è possibile selezionare, filtrare e manipolare.

from contact in dealer.DealerContacts select contact

o

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

Se non stai usando le proprietà di navigazione, perdi uno dei principali vantaggi di LINQ-to-SQL, la parte che mappa il grafico degli oggetti.


Oh amico, mi hai risparmiato tempo, non ho più bisogno di occuparmi di questi stupidi join!
Tomas,

23

fondamentalmente l' operatore di join LINQ non offre alcun vantaggio per SQL. Vale a dire la seguente query

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

comporterà INNER JOIN in SQL

join è utile per IEnumerable <> perché è più efficiente:

from contact in db.DealerContact  

la clausola verrebbe rieseguita per ogni rivenditore Ma per IQueryable <> non è così. Anche l' adesione è meno flessibile.


12

In realtà, spesso è meglio non aderire, in Linq che è. Quando ci sono proprietà di navigazione, un modo molto succinto per scrivere la tua istruzione linq è:

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

Si traduce in una clausola where:

SELECT <columns>
FROM Dealer, DealerContact
WHERE Dealer.DealerID = DealerContact.DealerID

Che aspetto ha una query LINQ con più clausole "from" (come in questo esempio) nella sintassi della catena di espressioni? È possibile?
Jon Schneider,

1
Il suo equivalente di sintassi del metodo è SelectMany().
Gert Arnold,

3

Utilizzare i join LINQ per eseguire il Join interno.

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

3

Prova questo :

     var data =(from t1 in dataContext.Table1 join 
                 t2 in dataContext.Table2 on 
                 t1.field equals t2.field 
                 orderby t1.Id select t1).ToList(); 

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

Benvenuto in Stack Overflow! Mentre questo frammento di codice può risolvere la domanda, inclusa una spiegazione aiuta davvero a migliorare la qualità del tuo post. Ricorda che stai rispondendo alla domanda per i lettori in futuro e che queste persone potrebbero non conoscere i motivi del tuo suggerimento sul codice. Cerca inoltre di non aggiungere il tuo codice a commenti esplicativi, in quanto ciò riduce la leggibilità sia del codice che delle spiegazioni!
Arrivederci StackExchange il

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

Dove le tabelle degli studenti e dei corsi hanno una chiave primaria e una relazione di chiave esterna


2

prova invece questo,

var dealer = from d in Dealer
             join dc in DealerContact on d.DealerID equals dc.DealerID
             select d;

1
var Data= (from dealer in Dealer join dealercontact in DealerContact on dealer.ID equals dealercontact.DealerID
select new{
dealer.Id,
dealercontact.ContactName

}).ToList();

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

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

Scrivi i nomi delle tabelle che desideri e inizializza la selezione per ottenere il risultato dei campi.


var list = (da u in db.Yourfirsttablename join c in db.secondtablename su u.firsttablecommonfields è uguale a c.secondtablecommon field dove u.Username == username seleziona 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 il

1

Unire interno due tabelle in 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 }

1

da d1 in DealerContrac unisciti a d2 in DealerContrac su d1.dealearid è uguale a d2.dealerid seleziona new {dealercontract. *}


Benvenuto in Stack Overflow! Questa risposta non aggiunge nulla alle risposte già esistenti.
Jeroen Heier,

-6

Un miglior esempio

Nomi tabella: TBL_EmpeTBL_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}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.