2015-03-03 3 views
0

У меня есть некоторые проблемы с запросом. Я постараюсь сделать это просто понятьLINQ сравнить 2 списка

У меня есть класс, который содержит два атрибута любит это

public class LanguageAndKnowledge{ 
public String LanguageCode{get;set;} 
public int LanguageKnowledge{get;set;} 
} 

Я использую другой класс, который из EntityFramework отображенной в соответствии с базой данных

public class Student{ 
... 
    public virtual ICollection<StudentLanguage> StudentLanguage { get; set; } 
} 

и класс StudentLanguage ..

public partial class StudentLanguage 
    { 
     public int StudentLanguageID { get; set; } 
     public System.Guid StudentID { get; set; } 
     public string LanguageCode { get; set; } 
     public int KnowledgeLevelID { get; set; } 
     public Nullable<System.DateTimeOffset> C_CreationDate { get; set; } 

     public virtual Student Student { get; set; } 
     public virtual Language Language { get; set; } 
    } 

Теперь она с пироги должны быть сложными. У меня есть список LanguageAndKnowledge так это выглядит

List<LanguageAndKnowledge> listLanguageKnowledge; 

Так что я начал фильтровать данные на моем объекте Student с запросом, как это и он работает

IQueryable<Student> students = model.Student.Where(stud => stud.StudentStudy.Any(study => selectedStudyType.Contains(study.StudyTypeID.Value) 
                            && selectedStudyDegree.Contains(study.StudyDegreeID.Value) 
                            && selectedYears.Contains(study.CompletionDate.Value.Year))); 

Второй шаг заключается в выборе от Student.StudentLanguage весь учащийся, у которого есть соответствующие данные из моего списка. Код языка и идентификатор знания являются некоторыми в обоих классах. Но я не понимаю, как я должен построить запрос. Я пробовал разные вещи, например, используя Any(), Contains(), но я не получил то, что хотел. я действительно не понимаю, как я должен сравнить два списка и мне нужна помощь :(

Например, я пытался что-то вроде этого ..

students.Where(stud=> stud.StudentLanguage 
.Any(lang=>listLanguageKnowledge.Contains(lang.LanguageCode)&&listLanguageKnowledge.Contains(lang.KnowledgeLevelId); 
//or 
students.Where(stud=> stud.StudentLanguage 
.Any(lang=>listLanguageKnowledge.Any(lang.LanguageCode)&&listLanguageKnowledge.Any(lang.KnowledgeLevelId); 

Редактировать
данных

StudentLanguage
Stud1 EN 4
Stud1 NL 4
Stud1 FR 4
Stud2 FR 3
Stud2 NL 4
Stud3 RU 4
Stud3 NL 4
Stud3 FR 2

List<LanguageAndKnowledge>
RU 4
NL 4
FR 4

Ожидаемый результат: Stud1

Поэтому я должен получить все данные, соответствующие этому списку.Мне нужно, чтобы получить весь студент, который имеет код и правильный идентификатор знания

+0

Просьба предоставить данные вашего образца и ожидаемый результат. – aush

+0

В ваших попытках я уверен, что вы по-прежнему выполняете одно сравнение (студенты, у которых это свойство 1 имеет это 1 точное значение), но на самом деле вам нужно сделать это несколько раз и обобщить результаты (учащиеся, где a или b или c ...). Есть много маршрутов, которые вы могли бы предпринять, но самым простым было бы перебирать одну коллекцию с циклом for, вызывать, где в другой коллекции внутри нее, и добавлять результаты в коллекцию, которую вы выделяете до цикла. После цикла вы, вероятно, должны дедупировать список. Надеюсь, что это поможет вам в правильном направлении. – evanmcdonnal

+0

Вы назначили результат студентам. Где (..) обратно к переменной студентов? В вашем примере в конце вашего вопроса, результат .Where отбрасывается. Например. изменить его на студентов = студентов. Где (....); – Sam

ответ

1

Поэтому я понял, что вам нужно найти студентов, которые знают все языковые коды с обязательным KnowledgeLevelId. Мне удалось выполнить репликацию, чтобы найти исправление (если я не понял проблему неправильно).

Мой результат соответствует ожидаемому результату.

Я создал эти классы:

public class Student 
    { 
     public string Name { get; set; } 
     public List<StudentLanguage> StudentLanguages { get; set; } 
    } 

    public class StudentLanguage 
    { 
     public string Name { get; set; } 
     public string LanguageCode { get; set; } 
     public int KnowledgeLevelId { get; set; } 
    } 

    public class LanguageKnowledge 
    { 
     public string LanguageCode { get; set; } 
     public int KnowledgeLevelId { get; set; } 
    } 

Тогда я написал этот код, чтобы заполнить ваш упомянутый данные:

private static List<Student> PopulateData() 
     { 
      var students = new List<Student> 
      { 
       new Student() 
       { 
        Name = "Student1", 
        StudentLanguages = new List<StudentLanguage>() 
        { 
         new StudentLanguage {KnowledgeLevelId = 4, LanguageCode = "EN"}, 
         new StudentLanguage {KnowledgeLevelId = 4, LanguageCode = "NL"}, 
         new StudentLanguage {KnowledgeLevelId = 4, LanguageCode = "FR"}, 
        } 
       } 
       , 
       new Student() 
       { 
        Name = "Student2", 
        StudentLanguages = new List<StudentLanguage>() 
        { 
         new StudentLanguage {KnowledgeLevelId = 3, LanguageCode = "FR"}, 
         new StudentLanguage {KnowledgeLevelId = 4, LanguageCode = "NL"}, 
        } 
       }, 
       new Student() 
       { 
        Name = "Student3", 
        StudentLanguages = new List<StudentLanguage>() 
        { 
         new StudentLanguage {KnowledgeLevelId = 4, LanguageCode = "EN"}, 
         new StudentLanguage {KnowledgeLevelId = 4, LanguageCode = "NL"}, 
         new StudentLanguage {KnowledgeLevelId = 2, LanguageCode = "FR"} 
        }, 
       } 
      }; 
      return students; 
     } 

А потом этот метод, чтобы найти необходимые данные:

private void FindData() 
     { 
      var students = PopulateData(); 

      var languageKnowledges = new List<LanguageKnowledge> 
      { 
       new LanguageKnowledge { KnowledgeLevelId = 4, LanguageCode = "EN"}, 
       new LanguageKnowledge { KnowledgeLevelId = 4, LanguageCode = "NL"}, 
       new LanguageKnowledge { KnowledgeLevelId = 4, LanguageCode = "FR"}, 
      }; 

      var studentLanguage = students.Where(
        student => DoesStudentHaveAllSkills(languageKnowledges, student.StudentLanguages)); 

      foreach (var student in studentLanguage) 
      { 
       MessageBox.Show(student.Name); 
      } 
     } 



     public bool DoesStudentHaveAllSkills(List<LanguageKnowledge> languageKnowledges, List<StudentLanguage> studentLanguages) 
     { 
      return 
       languageKnowledges.All(langKnow => studentLanguages.Any(studLang => studLang.KnowledgeLevelId.Equals(langKnow.KnowledgeLevelId) 
                  && studLang.LanguageCode.Equals(langKnow.LanguageCode))); 
     } 
+0

Я думаю, что это то, что я ищу. Если я правильно понимаю ваш код, я должен получить первое, и это именно то, что мне нужно. Я сейчас работаю над своим кодом, потому что обнаружил некоторые другие ошибки. Lol Большое спасибо :) –

+1

Нет проблем @Seb, не забудьте принять ответ ;-). Новое для сообщества, пытаясь создать какой-то репо lolz –

0

Я не уверен, что вы имеете в виду

все студента, которые имеют соответствующие данные из моего списка

, но это может работать для вас:

students.Where(stud => stud.StudentLanguage.Any(
    lang => listLanguageKnowledge.Any(lk => lk.LanguageCode == lang.LanguageCode && 
              lk.KnowledgeLevelId == lang.KnowledgeLevelId))); 
0

Попробуйте это, если он не работает, пожалуйста, предоставить образец в обоих списках.

students.Where(stud=> stud.StudentLanguage 
    .Any(lang=>listLanguageKnowledge 
     .Any(listItem => (listItem.LanguageCode == lang.LanguageCode) && 
          (listItem.LanguageKnowledge == lang.KnowledgeLevelId) 
      ) 
     ));