LINQ比较2个列表

时间:2015-03-03 19:37:53

标签: c# asp.net-mvc linq entity-framework

我实际上遇到了一些关于查询的问题。我会尽量让它变得简单易懂

我有一个包含两个属性的类,比如

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

现在,它开始变得棘手。我有一个ListAndKnowledge列表所以看起来像这样

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中选择所有拥有我列表中相应数据的学生。语言代码和知识id是两个类中的一些。但我不明白我应该如何构建查询。我尝试了不同的东西,比如使用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 EN 4
  Stud3 NL 4
  Stud3 FR 2

     

List<LanguageAndKnowledge>
  EN 4
  NL 4
  FR 4

     

预期成果:Stud1

所以我必须获得与列表匹配的所有数据。我需要让所有拥有代码和正确知识的学生

3 个答案:

答案 0 :(得分: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)));
        }

答案 1 :(得分:0)

我不确定你是什么意思

  

所有拥有我的列表中相应数据的学生

但这可能适合你:

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

答案 2 :(得分:0)

试试这个,如果它不起作用,请提供两个列表的样本。

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