¿Cuál es la sintaxis para una unión interna en LINQ to SQL?

443

Estoy escribiendo una instrucción LINQ to SQL, y busco la sintaxis estándar para una unión interna normal con una ONcláusula en C #.

¿Cómo representa lo siguiente en LINQ to SQL:

select DealerContact.*
from Dealer 
inner join DealerContact on Dealer.DealerID = DealerContact.DealerID
Glenn Slaven
fuente
Si tiene una clave externa entre las tablas, debe consultar la respuesta de Kirk Broadhurst a continuación.
Guilherme
1
Debes pluralizar los nombres de tus tablas. Una tabla que contenga (entradas sobre) muchos distribuidores debe llamarse distribuidores , y no distribuidores.
ANeves
55
@ANeves Está lejos de la práctica estándar usar nombres de tablas en plural, tanto el singular como el plural son perfectamente aceptables. Simplemente cambié de plural a singular para que coincida con los nombres de los objetos. Aquí la respuesta principal coincide en que el singular es más consistente (muchas pluralizaciones son raras o no existente - por ejemplo, '1 oveja, 8 ovejas': stackoverflow.com/questions/338156/…
niico
@niico este no es el lugar para discutir eso, supongo ... pero Microsoft Entity Framework pluraliza los nombres de las tablas , el ORM de Ruby on Rails pluraliza las tablas ... ¿está lo suficientemente cerca de la práctica estándar para usted? :) Contraargumento: NHibernate parece no pluralizar tablas .
ANeves
2
De hecho, algunas personas lo hacen de una manera, otras lo hacen de otra manera. No hay una práctica estándar. Personalmente, creo que singular tiene muchos más beneficios.
niico

Respuestas:

572

Va algo como:

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

Sería bueno tener nombres y campos sensibles para sus tablas para un mejor ejemplo. :)

Actualizar

Creo que para su consulta esto podría ser más apropiado:

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

Como está buscando los contactos, no los distribuidores.

Jon Limjap
fuente
11
gracias, de ahora en adelante usaré nombres sensibles como la mejor práctica que tiene sentido en linq, en lugar defrom c or from t1
shaijut
231

Y porque prefiero la sintaxis de la cadena de expresión, así es como lo haces con eso:

var dealerContracts = DealerContact.Join(Dealer, 
                                 contact => contact.DealerId,
                                 dealer => dealer.DealerId,
                                 (contact, dealer) => contact);
CleverPatrick
fuente
8
Si necesita filtrar o seleccionar campos de ambas tablas unidas, en lugar de solo campos de una de las dos tablas (la tabla DealerContact en el ejemplo de esta respuesta), aquí hay un ejemplo: stackoverflow.com/a/29310640/12484
Jon Schneider
52

Para extender la respuesta de sintaxis de la cadena de expresión de Clever Human:

Si desea hacer cosas (como filtrar o seleccionar) en los campos de ambas tablas que se unen, en lugar de solo en una de esas dos tablas, puede crear un nuevo objeto en la expresión lambda del parámetro final para el método Join incorporando ambas tablas, por ejemplo:

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 interesante es la expresión lambda en la línea 4 de ese ejemplo:

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

... donde construimos un nuevo objeto de tipo anónimo que tiene como propiedades los registros DealerContact y Dealer, junto con todos sus campos.

Luego podemos usar campos de esos registros a medida que filtramos y seleccionamos los resultados, como lo demuestra el resto del ejemplo, que usa dc_dcomo nombre para el objeto anónimo que construimos que tiene los registros DealerContact y Dealer como sus propiedades.

Jon Schneider
fuente
99
Las uniones con lambdas tienen una sintaxis horrible. Me niego a usarlo ;-)
Mariusz
12
@ Aristo No te culpo en absoluto. ¡Por lo general, debo consultar esta publicación para recordarme la sintaxis!
Jon Schneider
2
Algunas personas como yo prefieren la coherencia. Es por eso que busco específicamente la sintaxis 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
fuente
1
Hola, ¿puedes decirme de qué se trata esta parte? Estado = (ContactStatus) c.StatusID Estoy especialmente interesado en el fragmento: (ContactStatus) c.StatusID Saludos Mariusz
Mariusz
1
@aristo: mirando el código, supongo que ContactStatuses realmente una enumeración, y c.StatusIDno es realmente una identificación, sino el valor numérico de la enumeración. Si estoy en lo cierto, en (ContactStatus)c.StatusIDrealidad solo está lanzando un número entero a una enumeración.
Joel Mueller
25

Utilice el operador Linq Join :

var q =  from d in Dealer
         join dc in DealerConact on d.DealerID equals dc.DealerID
         select dc;
aku
fuente
1
¿Qué hacer cuando quiero columnas de ambos d & dc?
Kuntady Nithesh
1
@KuntadyNithesh Luego devuelva una clase que haya creado, como seleccionar nuevo MyCustomer {Id = dc.id, Id2 = d.id} ¡Eso es todo!
Elisabeth
25

Crea una clave externa y LINQ-to-SQL crea propiedades de navegación para usted. Cada uno Dealertendrá una colección de la DealerContactsque puede seleccionar, filtrar y manipular.

from contact in dealer.DealerContacts select contact

o

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

Si no está utilizando las propiedades de navegación, se está perdiendo uno de los principales beneficios de LINQ-to-SQL: la parte que asigna el gráfico del objeto.

Kirk Broadhurst
fuente
Oh hombre, me ahorraste tiempo, ¡ya no necesito lidiar con estas estúpidas uniones!
Tomás
23

Básicamente, el operador de unión LINQ no proporciona ningún beneficio para SQL. Es decir, la siguiente consulta

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

resultará en INNER JOIN en SQL

join es útil para IEnumerable <> porque es más eficiente:

from contact in db.DealerContact  

la cláusula se volvería a ejecutar para cada distribuidor. Pero para IQueryable <> no es el caso. También unirse es menos flexible.

the_joric
fuente
12

En realidad, a menudo es mejor no unirse, en linq, eso es. Cuando hay propiedades de navegación, una forma muy sucinta de escribir su declaración linq es:

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

Se traduce en una cláusula where:

SELECT <columns>
FROM Dealer, DealerContact
WHERE Dealer.DealerID = DealerContact.DealerID
Gert Arnold
fuente
¿Qué aspecto tiene una consulta LINQ con múltiples cláusulas "desde" (como en este ejemplo) en la sintaxis de la cadena de expresión? ¿Es posible?
Jon Schneider
1
Su método de sintaxis equivalente es SelectMany().
Gert Arnold
3

Utilice las uniones LINQ para realizar la unión 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
                   };
Uthaiah
fuente
3

Prueba esto :

     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
fuente
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
fuente
¡Bienvenido a Stack Overflow! Si bien este fragmento de código puede resolver la pregunta, incluir una explicación realmente ayuda a mejorar la calidad de su publicación. Recuerde que está respondiendo la pregunta para los lectores en el futuro, y que esas personas podrían no conocer los motivos de su sugerencia de código. ¡Intente también no saturar su código con comentarios explicativos, ya que esto reduce la legibilidad tanto del código como de las explicaciones!
Goodbye StackExchange el
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 };

Donde las tablas de alumnos y cursos tienen una clave principal y una relación de clave externa

Sandeep Shekhawat
fuente
2

intente esto,

var dealer = from d in Dealer
             join dc in DealerContact on d.DealerID equals dc.DealerID
             select d;
Milán
fuente
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
fuente
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
fuente
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();

Escriba los nombres de tabla que desee e inicialice la selección para obtener el resultado de los campos.

Sarfraj Sutar
fuente
var list = (desde u en db. Yourfirsttablename únete a c en db.secondtablename en u.firsttablecommonfields es igual a c.secondtablecommon campo donde 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}). Primero ();
Sarfraj Sutar
1

Interior unir dos tablas 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
fuente
1

desde d1 en DealerContrac, únase a d2 en DealerContrac en d1.dealearid es igual a d2.dealerid seleccione nuevo {dealercontract. *}

Rutu
fuente
¡Bienvenido a Stack Overflow! Esta respuesta no agrega nada a las respuestas ya existentes.
Jeroen Heier
-6

Un mejor ejemplo

Nombres de tabla: TBL_EmpyTBL_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
fuente