2010-07-01 29 views
6

tengo el siguiente método de firma:¿Cómo puedo usar linq para devolver enteros en una matriz que no coinciden con una propiedad entera de otra matriz?

internal static int[] GetStudentIDsThatAreNotLinked(PrimaryKeyDataV1[] 
     existingStudents, IQueryable<Student> linkedStudents) 

PrimaryKeyData es una clase que tiene enteros serverID y localId como propiedades. El alumno es una clase que (entre otras propiedades) tiene un entero llamado StudentID.

En Inglés, lo que quiero hacer es devolver una matriz de enteros que están en existingStudents [...]. ServerID pero no en linkedStudents [...]. StudentID

Si existingStudents '' y ' linkedStudents eran ambas matrices de enteros, usaría una consulta linq como a continuación:

return from es in existingStudents where 
    !linkedStudents.Contains<int>(es) select es; 

..which entonces se podría convertir a una matriz de enteros.

Lo que quiero hacer es darle contiene un IEqualityOperator que se consideran una clase PrimaryKeyData a ser igual a una clase Estudiantes si PrimaryKeyData.ServerID == Student.StudentID

Así que creo que necesito una expresión lambda pero Estoy muy confundido sobre cómo se construiría eso.

Creo que voy en la dirección correcta, pero ¿alguien puede ayudarme a superar el obstáculo final?

Respuesta

5

lo tanto, mi opinión es que desea obtener todas las instancias de PrimaryKeyDataV1 cuya ServerID propiedad no existe en cualquiera de los bienes de los students.StudentID linkedStudents ¿parámetro?

internal static PrimaryKeyDataV1[] GetStudentsThatAreNotLinked(PrimaryKeyDataV1[] existingStudents, IQueryable<Student> linkedStudents) 
{ 
    var results = existingStudents.Select(s => s.ServerID) 
     .Except(linkedStudents.Select(link => link.StudentID)) 
     .ToArray(); 

    return existingStudents.Where(stud => results.Contains(stud.ServerID)); 
} 

O si lo que desea es una matriz de ID ...

internal static int[] GetStudentIDsThatAreNotLinked(PrimaryKeyDataV1[] existingStudents, IQueryable<Student> linkedStudents) 
{ 
    return existingStudents.Select(s => s.ServerID) 
     .Except(linkedStudents.Select(link => link.StudentID)) 
     .ToArray(); 
} 
2

Si sólo necesita devolver los identificadores, se puede usar algo como:

existingStudents.Select(es => es.StudentID) 
       .Except(linkedStudents.Select(ls => ls.ServerID)); 

Puede escribir esto en forma comprensión de consulta, pero creo que es menos claro:

var result = (from es in existingStudents select es.StudentID); 
      .Except 
      (from ls in linkedStudents select ls.ServerID) 

Si necesita devolver el resultado como una matriz, sólo tiene que utilizar el .ToArray() extensión:

existingStudents.Select(es => es.StudentID) 
       .Except(linkedStudents.Select(ls => ls.ServerID)).ToArray(); 

No necesita crear su propio comparador de igualdad en el caso de que solo necesite devolver la diferencia establecida en los ID.

+0

Me apreciar el detalle adicional en la comprensión de consulta, pero por desgracia, la consulta devuelve el linkedstudents que no están en existingstudents pero necesitaba la estudiantes existentes que no están en los estudiantes vinculados –

+0

@Neil: Mis disculpas ... Repararé mi respuesta. – LBushkin

+0

Gracias y marcado. Es una lástima que no podamos aceptar respuestas múltiples, ya que ambos estaban más o menos en el dinero. –

0
List<student> ExistingStudents = new List<student>(); 
    List<student> LinkedStudents = new List<student>(); 

    ExistingStudents.Add(new student {id=1, name="joe"}); 
    ExistingStudents.Add(new student { id = 2, name = "beth" }); 
    ExistingStudents.Add(new student { id = 3, name = "sam" }); 

    LinkedStudents.Add(new student { id = 2, name = "beth" }); 


    var students = from stud in ExistingStudents 
        where !(LinkedStudents.Select(x => x.id).Contains(stud.id)) 
        select stud; 

    foreach(student s in students) 
    { 
     System.Diagnostics.Debug.WriteLine(string.Format("id: {0}, name: {1}", s.id, s.name)); 
    } 

clase simple estudiante:

public class student 
{ 
    public int id; 
    public string name; 
} 
Cuestiones relacionadas