Я действительно очень смущен вашим запросом 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);
}
Редактировать
Я все еще очень смущен этим вопросом. Итак, вы дали следующие требования:
- имеют 2 предложения where в инструкции linq xml
- имеет два предложения where в одном операторе add для объекта словаря
- ВЫБРАТЬ * ИЗ МОИХ ДАННЫХ
- отфильтровывают те, которые не являются 1-процентным
Я проигнорирую первые два, потому что я не думаю, что они необходимы. Третье требование относительно простое, если предположить, что ваш формат данных несколько фиксирован. (Вы действительно хотели иметь один тег "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
ГДЕ только статистика = "0 процентиль,
25 процентиль, 50 процентиль, 75
процентиль "и т. д.
Итак, когда вы говорили о пунктах 2 where, вы подразумевали, что вы хотите, например, "где процентиль = 0 или процентиль = 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);