【问题标题】:How do you have 2 where clauses in a linq xml statement您如何在 linq xml 语句中有 2 个 where 子句
【发布时间】:2010-12-07 17:06:12
【问题描述】:

我有以下 XML,当您通过特定统计时,我需要一个查询来提取年份和 Return_Value。

当前代码不起作用,因为在一个字典对象的 add 语句中不能有两个 where 子句。这个问题有方法解决吗?

foreach (var row in rows)
{
    myHoldingsDistribution.Add(row.Descendants()
        .Where(y => y.Name.LocalName == keyName)
        .Select(q => q.Value).Max(), 
        Double.Parse(row.Descendants().Where(y => y.Name.LocalName == valueName)
                           .Select(q => q.Value).Max()) * multiplier);

<Table>
  <Year>1</Year>
  <Statistic>0 Percentile</Statistic>
  <Return_Value>0.0535644000000</Return_Value>
</Table>
    base {System.Xml.Linq.XContainer}: <Table>
  <ALMRunResults_Year>1</ALMRunResults_Year>
  <Statistic>0 Percentile</Statistic>
  <Return_Value>0.0535644000000</Return_Value>
</Table>

    FirstAttribute: null
    HasAttributes: false
    HasElements: true
    IsEmpty: false
    LastAttribute: null
    Name: {Table}
    NodeType: Element
    Value: "10 Percentile0.0535644000000"

编辑

在下面的语句中 - 理想情况下,我希望 .where 两次过滤掉那些不是 1 Percentile 的。

 myHoldingsDistribution.Add(row.Descendants() 
        .Where(y => y.Name.LocalName == keyName) 
        .Select(q => q.Value).Max(),  
        Double.Parse(row.Descendants().Where(y => y.Name.LocalName == valueName) 
                           .Select(q => q.Value).Max()) * multiplier); 

【问题讨论】:

  • “你不能有两个 where 子句”是什么意思?您从提供的代码中得到什么错误?
  • “理想情况下,我希望 .where 两次过滤掉那些不是 1 Percentile 的。” ——是什么阻止了你?您通常可以将 .Where 语句链接在一起:rows.Where(...).Where(...) 当您尝试此操作时会发生什么,代码是什么样的?

标签: xml linq silverlight dictionary


【解决方案1】:

我对您的 LINQ 查询感到非常困惑,您在第一段中描述的行为似乎并不能真正反映您的代码试图做什么。我相信您在代码中遇到的问题与 Double.Parse 方法的放置有关,因为以下代码可以编译并运行得很好:

var myHoldingsDistribution = new Dictionary<object, object>();
var rows = new[] {new {Descendants = new[]{new {Name = new {LocalName = "test"}, Value = 0.05}}}};
var keyName = "test";
var valueName = "test";
var multiplier = 2d;
foreach (var row in rows)
{
    myHoldingsDistribution.Add(row.Descendants
        .Where(y => y.Name.LocalName == keyName)
        .Select(q => q.Value).Max(), 
        row.Descendants.Where(y => y.Name.LocalName == valueName)
                        .Select(q => q.Value).Max() * multiplier);

}

编辑

这个问题我还是很困惑。到目前为止,您已经给出了以下要求:

  1. 在 linq xml 语句中有 2 个 where 子句
  2. 在一个字典对象的 add 语句中有两个 where 子句
  3. 从我的数据集中选择 *
  4. 过滤掉那些不是 1 Percentile

我将忽略前两个,因为我认为它们没有必要。第三个要求相对简单,假设您的数据格式有些固定。 (您真的是要拥有一个“Year”标签和一个“ALMRunResults_Year”标签吗?)

// Move the data into an object that can easily be manipulated.
var transform = from r in rows
                select new 
                {
                    key = r.Element(keyName).Value,
                    value = Double.Parse(r.Element(valueName).Value),
                    statistic = r.Element(statisticName).Value
                };

一旦您像这样选择了值,您就可以使用 LINQ to Objects 来执行您所描述的过滤器,并通过调用 ToDictionary 从结果集合中创建一个字典:

var myHoldingsDistribution = transform
    // Filter out anybody that's not 1 percentile
    .Where(r => r.statistic == statisticFilter)
    // Create a dictionary out of the keys and values
    .ToDictionary(r => r.key, r => r.value);

我给你的两个代码块在以下设置下编译并运行得很好:

var text = 
@"<Root>
    <Table>
        <ALMRunResults_Year>1</ALMRunResults_Year>
        <Statistic>0 Percentile</Statistic>
        <Return_Value>0.0535644000000</Return_Value>
    </Table>
    <Table>
        <ALMRunResults_Year>2</ALMRunResults_Year>
        <Statistic>1 Percentile</Statistic>
        <Return_Value>0.0535644000000</Return_Value>
    </Table>
</Root>";
var doc = XDocument.Parse(text);
var rows = doc.Descendants("Table");

var keyName = "ALMRunResults_Year";
var valueName = "Return_Value";
var statisticName = "Statistic";
var statisticFilter = "1 Percentile";

这有意义吗?

编辑 2

WHERE 仅统计 = “0 个百分位, 25%, 50%, 75 百分位数”等

所以当您谈论 2 个 where 子句时,您的意思是您想要“例如 where percentile = 0 或 percentile = 25”?有几种方法可以做到这一点。最简单的可能是使用Contains 方法:

var statisticFilters = new[]{
    "0 Percentile", "25 Percentile", "50 Percentile", "75 Percentile"
};
...
var myHoldingsDistribution = transform
    .Where(r => statisticFilters.Contains(r.statistic))
    .ToDictionary(r => r.key, r => r.value);

【讨论】:

  • 基本上我想从我的数据集中选择 *
  • WHERE Statistic only = "0 percentile, 25 percentile, 50 percentile, 75 percentile" 等并忽略所有其他标签,例如 "99 percentile" 等
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-19
相关资源
最近更新 更多