Qual é a sintaxe para uma junção interna no LINQ to SQL?


443

Estou escrevendo uma instrução LINQ to SQL e estou após a sintaxe padrão para uma junção interna normal com uma ONcláusula em C #.

Como você representa o seguinte no LINQ to SQL:

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

Se você tiver uma chave estrangeira entre as tabelas, procure a resposta de Kirk Broadhurst abaixo.
Guilherme

1
Você deve pluralizar seus nomes de tabela. Uma tabela contendo (entradas sobre) muitos revendedores deve ser chamada de revendedor , e não revendedor.
ANeves 21/08

5
@ANeves Está longe da prática padrão usar nomes de tabelas plurais, tanto o singular quanto o plural são perfeitamente aceitáveis ​​- apenas mudei de plural para singular para corresponder aos nomes dos objetos - aqui a resposta principal concorda que o singular é mais consistente (muitas pluralizações são estranhas ou não existente - por exemplo, '1 ovelha, 8 ovelhas': stackoverflow.com/questions/338156/…
niico

@niico este não é o lugar para discutir isso, eu acho ... mas o Microsoft Entity Framework pluraliza os nomes das tabelas, o ORM do Ruby on Rails pluraliza as tabelas ... isso é próximo o suficiente da prática padrão para você? :) Contra-argumento: NHibernate parece não pluralizar tabelas .
ANeves

2
De fato - algumas pessoas fazem isso de uma maneira - outras fazem isso de outra maneira. Não há prática padrão. Pessoalmente, acho que o singular tem muito mais benefícios.
Niico 11/06

Respostas:


572

É algo como:

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

Seria bom ter nomes e campos sensatos para suas tabelas para um exemplo melhor. :)

Atualizar

Eu acho que para sua consulta isso pode ser mais apropriado:

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

Como você está procurando os contatos, não os revendedores.


11
obrigado, a partir de agora vou usar nomes sensíveis como a melhor prática que faz sentido em LINQ, em vez defrom c or from t1
shaijut

231

E como eu prefiro a sintaxe da cadeia de expressão, eis como você faz isso:

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

8
Se você precisar filtrar ou selecionar nos campos das duas tabelas unidas, em vez de apenas nos campos de uma das duas tabelas (a tabela DealerContact no exemplo desta resposta), veja um exemplo: stackoverflow.com/a/29310640/12484
Jon Schneider

52

Para estender a resposta da sintaxe da cadeia de expressão por Clever Human:

Se você quiser fazer coisas (como filtrar ou selecionar) nos campos de ambas as tabelas serem unidas - em vez de apenas uma dessas duas tabelas -, poderá criar um novo objeto na expressão lambda do parâmetro final para o método Join incorporando essas duas tabelas, por exemplo:

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

A parte interessante é a expressão lambda na linha 4 desse exemplo:

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

... onde construímos um novo objeto do tipo anônimo que tem como propriedades os registros DealerContact e Dealer, juntamente com todos os seus campos.

Em seguida, podemos usar os campos desses registros à medida que filtramos e selecionamos os resultados, conforme demonstrado no restante do exemplo, que usa dc_dcomo nome o objeto anônimo que construímos que possui os registros DealerContact e Dealer como suas propriedades.


9
Associações com lambdas têm uma sintaxe terrível. Recuso-me a usá-lo ;-)
Mariusz

12
@aristo Eu não culpo você. Normalmente, tenho que voltar a este post para me lembrar da sintaxe!
Jon Schneider

2
Algumas pessoas como eu preferem consistência. É por isso que procuro a sintaxe lambda especificamente.
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
Oi, Você pode me dizer por favor o que é esta parte? Status = (ContactStatus) c.StatusID Estou interessado especialmente no fragmento: (ContactStatus) c.StatusID Atenciosamente Mariusz
Mariusz

1
@aristo - olhando para o código, acho que ContactStatusé realmente um enum, e c.StatusIDnão é realmente um ID, mas o valor numérico do enum. Se eu estiver certo, (ContactStatus)c.StatusIDé realmente apenas converter um número inteiro para um enum.
Joel Mueller

25

Use o operador Linq Join :

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

1
o que fazer quando eu quero colunas de ambos d & dc?
Kuntady Nithesh

1
@KuntadyNithesh Em seguida, retorne uma classe que você criou, como selecione new MyCustomer {Id = dc.id, Id2 = d.id} É isso!
Elisabeth

25

Você cria uma chave estrangeira e o LINQ-to-SQL cria propriedades de navegação para você. Cada Dealerum terá uma coleção da DealerContactsqual você pode selecionar, filtrar e manipular.

from contact in dealer.DealerContacts select contact

ou

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

Se você não estiver usando propriedades de navegação, estará perdendo um dos principais benefícios do LINQ-to-SQL - a parte que mapeia o gráfico de objetos.


Oh cara, você economizou meu tempo, não preciso mais lidar com essas idiotas!
Tomas

23

basicamente, o operador de junção LINQ não oferece nenhum benefício para o SQL. Ou seja, a seguinte consulta

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

resultará em INNER JOIN no SQL

join é útil para IEnumerable <> porque é mais eficiente:

from contact in db.DealerContact  

A cláusula seria reexecutada para todos os revendedores. Mas para IQueryable <> não é o caso. A junção também é menos flexível.


12

Na verdade, muitas vezes é melhor não participar do linq. Quando existem propriedades de navegação, uma maneira muito sucinta de escrever sua instrução linq é:

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

Isso se traduz em uma cláusula where:

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

Como é uma consulta LINQ com várias cláusulas "from" (como neste exemplo) na sintaxe da cadeia de expressão? É possível?
Jon Schneider

1
Seu equivalente de sintaxe de método é SelectMany().
Gert Arnold

3

Use as junções LINQ para executar a junção interna.

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

Tente o seguinte:

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

Bem-vindo ao Stack Overflow! Embora esse trecho de código possa resolver a questão, incluir uma explicação realmente ajuda a melhorar a qualidade da sua postagem. Lembre-se de que você está respondendo à pergunta dos leitores no futuro e essas pessoas podem não saber os motivos da sua sugestão de código. Tente também não sobrecarregar seu código com comentários explicativos, pois isso reduz a legibilidade do código e das explicações!
Adeus 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 };

Onde as tabelas de alunos e cursos têm relação de chave primária e chave estrangeira


2

tente ao invés disso,

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

Escreva os nomes das tabelas desejadas e inicialize a seleção para obter o resultado dos campos.


var list = (from u in db.Yourfirsttablename join c in db.secondtablename em u.firsttablecommonfields é igual a c.secondtablecommon field em que u.Username == username seleciona novo {u.UserId, u.CustomerId, u.ClientId, u.RoleId , u. nome de usuário, u.E-mail, u.Password, u.Salt, u.Hint1, u.Hint2, u.Hint3, u.Locked, u.Active, c.ProfilePic}). First ();
Sarfraj Sutar

1

Junção interna de duas tabelas no 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

de d1 no DealerContrac, junte-se ao d2 no DealerContrac em d1.dealearid é igual a d2.dealerid selecione novo {dealercontrato. *}


Bem-vindo ao Stack Overflow! Esta resposta não adiciona nada às respostas já existentes.
Jeroen Heier 9/08/19

-6

Um melhor exemplo

Nomes da tabela: 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}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.