这个LINQ语句在使用中是否正确?

时间:2012-04-01 10:08:32

标签: c# linq linq-to-xml

我正在尝试查找并收集满足这些要求的所有元素:

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>

在搜索最低兄弟时,是否与我选择一个兄弟姐妹有关?即我首先搜索先决条件,然后说要选择它的Name.Value(checkTest

即使我尝试将if语句设为!=,它也会打印每个先决条件,即使它没有![/ p>

1 个答案:

答案 0 :(得分:2)

问题是checkTestIEnumerable<String>,而不是字符串,因此调用ToString()并不能提供比较好的价值。仅供参考 - 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之前的问题更新答案

从我昨天早上给你的关于类似话题的answer开始,您使用的是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查询中,您选择的是具有先决条件的Names列表,但您要尝试与仅包含代码的先决条件列表进行比较。

您应该使用我提供的查询来检查匹配项,但是您应该使用以下内容获取checkTest

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

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

要回复您的上一条评论,我提供给您的查询是LINQ查询的另一种形式,我倾向于更小/更短的查询。

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

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

=&gt; operator被称为lamda表达式。尝试搜索LINQ查询语法和/或Lambda表达式以帮助理解差异