此LINQ语句在使用中是否正确

本文关键字:是否 LINQ 语句 | 更新日期: 2023-09-27 18:29:43

我正在努力寻找并收集所有满足这些要求的元素:

var checkTest = from d in document.Descendants("Prerequisite")
                where d.Value != "none"
                select d.Parent.Element("Name").Value;

通过使用foreach循环:

foreach (var item in prerequisite)
{
    if (item == checkTest.ToString())
    {
        MessageBox.Show("this module has a prereq" + item);
    }
}

但出于某种原因,它不会有任何作用,有人知道为什么吗?我认为问题出在var checkTest

(这就是foreach中的先决条件:)

var prerequisite = from d in document.Descendants("Name")
                   where d.Value == (String)listBox2.SelectedItem
                   select d.Parent.Element("Prerequisite").Value;

这是XML:

<?xml version="1.0" encoding="utf-8" ?>
<SoftwareEngineering>
  <Module>
    <Name>Algorithms and Data Structures</Name>
    <Code>3SFE504</Code>
    <Capacity>5</Capacity>
    <Semester>1</Semester>
    <Prerequisite>none</Prerequisite>
  </Module>
  <Module>
    <Name>3D Graphics I</Name>
    <Code>3SFE508</Code>
    <Capacity>5</Capacity>
    <Semester>1</Semester>
    <Prerequisite>none</Prerequisite>
  </Module>
  <Module>
    <Name>Event-Driven Programming</Name>
    <Code>3SFE513</Code>
    <Capacity>10</Capacity>
    <Semester>1</Semester>
    <Prerequisite>none</Prerequisite>
  </Module>
  <Module>
    <Name>Object Oriented Design</Name>
    <Code>3SFE514</Code>
    <Capacity>10</Capacity>
    <Semester>1</Semester>
    <Prerequisite>none</Prerequisite>
  </Module>
  <Module>
    <Name>Requirements Engineering</Name>
    <Code>3SFE516</Code>
    <Capacity>10</Capacity>
    <Semester>1</Semester>
    <Prerequisite>none</Prerequisite>
  </Module>
  <Module>
    <Name>Introduction to AI</Name>
    <Code>3SFE599</Code>
    <Capacity>5</Capacity>
    <Semester>1</Semester>
    <Prerequisite>none</Prerequisite>
  </Module>
  <Module>
    <Name>Java Mobile Application Development</Name>
    <Code>3SFE540</Code>
    <Capacity>5</Capacity>
    <Semester>1</Semester>
    <Prerequisite>3SFE514(corequisite)</Prerequisite>
  </Module>
  <Module>
    <Name>C# .NET Programming</Name>
    <Code>3SFE541</Code>
    <Capacity>5</Capacity>
    <Semester>1</Semester>
    <Prerequisite>3SFE514(corequisite)</Prerequisite>
  </Module>
  <Module>
    <Name>Software Engineering Group Project</Name>
    <Code>3SFE515</Code>
    <Capacity>5</Capacity>
    <Semester>2</Semester>
    <Prerequisite>3SFE514(corequisite)</Prerequisite>
  </Module>
  <Module>
    <Name>Software Engineering</Name>
    <Code>3SFE519</Code>
    <Capacity>10</Capacity>
    <Semester>2</Semester>
    <Prerequisite>none</Prerequisite>
  </Module>
  <Module>
    <Name>Mobile User Interface Development</Name>
    <Code>3SFE542</Code>
    <Capacity>5</Capacity>
    <Semester>2</Semester>
    <Prerequisite>3SFE540</Prerequisite>
  </Module>
  <Module>
    <Name>Interactive Multimedia</Name>
    <Code>3MTS954</Code>
    <Capacity>5</Capacity>
    <Semester>2</Semester>
    <Prerequisite>none</Prerequisite>
  </Module>
  <Module>
    <Name>Concurrent Programming</Name>
    <Code>3SFE555</Code>
    <Capacity>5</Capacity>
    <Semester>2</Semester>
    <Prerequisite>none</Prerequisite>
  </Module>
  <Module>
    <Name>Mobile Gaming</Name>
    <Code>3SFE557</Code>
    <Capacity>10</Capacity>
    <Semester>2</Semester>
    <Prerequisite>none</Prerequisite>
  </Module>
  <Module>
    <Name>Intelligent Systems</Name>
    <Code>3SFE500</Code>
    <Capacity>10</Capacity>
    <Semester>2</Semester>
    <Prerequisite>3SFE599</Prerequisite>
  </Module>
  <Module>
    <Name>3D Graphics II</Name>
    <Code>3SFE501</Code>
    <Capacity>10</Capacity>
    <Semester>2</Semester>
    <Prerequisite>3SFE508</Prerequisite>
  </Module>
</SoftwareEngineering>

这和我在搜索最低的兄弟姐妹时选择一个较高的兄弟姐妹有关系吗?即,我先搜索先决条件,然后说选择其名称。值(在checkTest中)

即使我尝试将if语句设置为!=,它将打印每个先决条件,即使没有!

此LINQ语句在使用中是否正确

问题是checkTestIEnumerable<String>,而不是字符串,所以调用ToString()也不能提供好的比较值。FYI-IEnumerable<T>是所有基本LINQ查询的返回值,尽管有提取第一个或最后一个元素的方法。

看起来您正试图获得与checkTest 中的某个元素匹配的先决条件列表

所以你应该试试这样的东西:

var match = prerequisite.Where(x => checkTest.Contains(x)).Select(item => item);
foreach (var pr in match)
{
    MessageBox.Show("this module has a prereq" + pr);
}

编辑:根据OP之前的问题更新答案

根据我昨天早上就类似主题给你的答案,你在用Module类和Dictionary<String,Module>吗?如果是,为什么要进行此查询?您已经拥有了无需查询即可完成此任务所需的一切:

var pr = modules[(String)listBox1.SelectedValue].Prerequisite;
if (pr != "none")
    MessageBox.Show("this module has a prereq" + pr);

第二次编辑以回答实际的LINQ查询问题

我之前的编辑建议回到以前的问题并起诉预装的XML和集合仍然是一个更好的解决方案,但由于您的问题似乎又回到了使用LINQ to XML,因此您显然有理由更喜欢它。

我更详细地看了你的问题,我想我有问题。您正在比较两个永远不会匹配的元素。在checkTest查询中,您选择了一个具有prereq的Names列表,但您试图与一个仅包含代码的prereq列表进行比较。

你应该使用我提供的查询来检查匹配,但你应该得到checkTest,如下所示:

var checkTest = from d in xdoc.Descendants("Prerequisite")
                where d.Value != "none"
                select d.Parent.Element("Prerequisite").Value;

EDIT#3-使用LINQ查询语法重写

为了回应您的最后一条评论,我为您提供的查询是LINQ查询的另一种形式,我倾向于选择较小/较短的查询。

您可以使用您一直使用的查询语法将该查询重写为:

var match = from x in prerequisite
            where checkTest.Contains(x)
            select x;

=>运算符称为λ表达式。尝试搜索LINQ查询语法和/或Lambda表达式,以帮助理解的差异