2010-10-25 17 views
5

Tengo tres objetos (splistitemcollection) que estoy uniendo entre sí, que funciona muy bien, pero el problema que tengo es que hay una relación de uno a muchos entre el objeto de un contrato y un objeto de los clientes. Necesito obtener solo el primer objeto del cliente para cada objeto del contrato durante la unión.LINQ Únete en la parte superior 1

Aquí es lo que estoy haciendo

 
(Contract)(Customer) 
12345 John Smith 
12345 Jane Smith 
67890 howard Jones 
67890 Mary Jones 

Aquí es lo que quiero 12345 (sólo uno de los clientes, Jane o John)

Aquí está el código im usando actualmente.

var joinedResults = from SPListItem contracts in _contractList 
         join SPListItem customers in _customerList 
         on contracts["ContractNumber"] equals customers["ContractNumber"] 
         join SPListItem loans in _loanList 
         on contracts["ContractNumber"] equals loans["Contract_x0020_Number"] 
         into l from loans in l.DefaultIfEmpty() 
         select new MergedData(contracts, customers, loans); 

En SQL i definiría una cláusula de selección de la parte superior en una sub consulta definido en mi unirse, simplemente no puedo hacerme a la sintaxis de mi cerebro novato LINQ.

resultado final

var joinedResults = from SPListItem contracts in _contractList 
     join SPListItem customers in 
     // Derived subset 
     (from SPListItem customers in _customerList 
     group customers by customers["ContractNumber"] into groupedCustomers 
     select groupedCustomers.FirstOrDefault() 
    ) on contracts["ContractNumber"] equals customers["ContractNumber"] 
     join SPListItem loans in _loanList 
     on contracts["ContractNumber"] equals loans["Contract_x0020_Number"] into l 
     from loans in l.DefaultIfEmpty() 
     select new MergedData(contracts, customers, loans); 
+0

Gracias a todos por la ayuda. Usando el concepto de grupo, pude obtener los resultados que necesitaba. De hecho, moví el grupo de un enunciado separado a en línea en la consulta. Aquí estaban los resultados –

Respuesta

4

Lo explicaré primero, porque el LINQ a veces parece confuso. La idea es hacer consultas a sus clientes, y agrupar por el ContractNumber, y luego tomar el primero. Si lo desea, puede ordenar por algún campo, para que sea más determinista (siempre tomando el nombre más bajo en orden alfabético, etc.) Luego, únase a su tempQuery que será básicamente el primer cliente (número de contrato).

var tempQuery = from SPListItem customers in _customerList 
    group customers by customers["ContractNumber"] into gby 
    select gby.First(); 


var joinedResults = 

    from SPListItem contracts in _contractList 
    join SPListItem customer in tempQuery 
on contract["ContractNumber"] equals customer["ContractNumber"] 
    join SPListItem loans in _loanList 
on contracts["ContractNumber"] equals loans["Contract_x0020_Number"] 
into l from loans in l.DefaultIfEmpty() 
select new MergedData(
    contracts, 
    customer, 
    loans 
    ); 

} 
+0

muchas gracias, estoy más interesado en el concepto de comprensión que solo una sintaxis de código y que sin duda tiene sentido separar la separación, me imagino que sería un rendimiento más rápido también en lugar de tener que unirse en cada fila y luego filtra solo el primero. –

+0

Mi SP VM no está jugando bien esta mañana, así que acabo de probar lo anterior (con ListItemCollection y ListItem) y debería hacer lo que quiera. ¿Tiene sentido lo anterior? – Nix

0
var joinedResults = (from SPListItem contracts in _contractList 
         join SPListItem customers in _customerList 
         on contracts["ContractNumber"] equals customers["ContractNumber"] 
         join SPListItem loans in _loanList 
         on contracts["ContractNumber"] equals loans["Contract_x0020_Number"] 
         into l from loans in l.DefaultIfEmpty() 
         select new MergedData(contracts, customers, loans)).FirstOrDefault(); 

Sólo tiene que llamar método FirstOrDefault para seleccionar el primer elemento encontrado.

+0

gracias por la respuesta, y me di cuenta de que me estaba perdiendo una parte crítica de mi descripción. Quiero todos los registros de los contratos, y solo uno de los registros coincidentes de los clientes. Básicamente, FirstOrDefault es correcto, pero solo para los clientes. Algo como esto funcionaría? –

0

Esto es como una peonza (1) punto por cada consulta devuelve contrato:

var joinedResults = from SPListItem contracts in _contractList 
         join SPListItem loans in _loanList 
         on contracts["ContractNumber"] equals loans["Contract_x0020_Number"] 
         into l from loans in l.DefaultIfEmpty() 
         select new MergedData(contracts, 
         customer = _customerList.Where(c => c["ContractNumber"] == contracts["ContractNumber"].FirstOrDefault() 
         , loans); 
Cuestiones relacionadas