Я пытаюсь суммировать некоторые значения за год. Мой код выполняется в день, поэтому после вычислений мне нужно суммировать эти значения. Цель состоит в том, чтобы экспортировать их обратно в SQL. Я уже настроил таблицу, и мне удалось экспортировать в нее некоторые значения, но только ежедневные, а не годовые.
// YEAR OVERVIEW
OptResultDataYear optResultDataYear = new OptResultDataYear();
// Variations in price
List<float> varprijs = new List<float> { 0.06f, 0.08f, 0.10f, 0.12f, 0.14f, 0.16f, 0.18f };
// Create dictionaries for storing the values
Dictionary<float, OptResultYear> yearlyResults = varPrijs.ToDictionary(co => co, co => new OptResultYear { AfdelingId = afd.AfdelingsId, variatiePrijs = co });
// SQL output
OptResultYear optResultYear= new OptResultYear();
for (DateTime date = startYear; date < endYear; date = date.AddDays(1))
{
foreach (float co in varprijs)
{
// Calculate the optimal results with the varPrijs
ResultScenDay optResultvar = await DayCalc.RunOcapOptimaalDayAsync(afd.AfdelingsId, date, 3600, (int)ScenarioType.Optimal, co, null); // per dag met uurdata.
// Analyze the code
optResultYear = analysePeriode.FillOptResultYear(afd.AfdelingsId, kenm.TeeltOppHa, date, optResultvar, co, null);
// Collect the required values
yearlyResults[co].OptTotalDos += (float)optResultYear.OptTotalDos;
yearlyResults[co].OptDos1 += (float)optResultYear.OptDos1;
yearlyResults[co].OptDos2 += (float)optResultYear.OptDos2;
yearlyResults[co].OptCost += (float)optResultYear.OptCost;
yearlyResults[co].OptProductie += (float)optResultYear.OptProductie;
yearlyResultsCO2[co].OptConcLp += (float)optResultYear.OptConcLp;
// Set the date for the last entry
yearlyResultsCO2[co].Datum = date;
}
}
Значения справа (optResultYear.) имеют значения, и они рассчитываются по мере необходимости. Однако при добавлении их в свой словарь я получаю только значения NULL.
Кто-нибудь знает, как решить эту проблему или знает лучший вариант?
var yr = yearlyResults[co]; yr.OptTotalDos = (yr.OptTotalDos ?? 0f) + (float)optResultYear.OptTotalDos; yr.OptDos1 = (yr.OptDos1 ?? 0f) + (float)optResultYear.OptDos1; .... Но пусть это можно будет сделать в SQL с помощью агрегатов GROUP BY YEAR(date) и SUM(xy).
@jdweng Я все еще новичок в C#, поэтому не знал, что словари автоматически имеют нулевые значения.
@OlivierJacot-Decombes Спасибо за это, мне нужно, чтобы это было сделано на C# вместо SQL, но ??0f работает по мере необходимости. Спасибо вам, ребята, за вашу помощь.
Обязательное предупреждение об использовании типов с плавающей запятой для денежных сумм. Суммы могут привести не к тому, чего вы ожидаете.
Кроме того, float — ужасный тип для использования в качестве ключа словаря: два значения с плавающей запятой, которые должны быть идентичными, могут иметь разные фактические значения и хэш-коды. Поскольку вы используете фиксированный набор постоянных значений, вы, вероятно, этого не видите, но integer было бы лучше (уменьшив их на 100).





Решение заключалось в том, что добавление значения NULL к фактическому значению превращается в значение NULL. Поэтому,
var yr = yearlyResults[co];
yr.OptTotalDos = (yr.OptTotalDos ?? 0f) + (float)optResultYear.OptTotalDos;
Добавление yr.OptTotalDos ?? 0f гарантировало, что если значение равно NULL, то значение будет изменено на 0, что приведет к продолжению вычислений.
Обратите внимание, что значение по умолчанию для типа, допускающего значение NULL, — null и null распространяется. То есть, null + x == null.
Вы можете использовать оператор объединения нулей ??, чтобы преобразовать нулевое значение в желаемое значение.
То есть, (null ?? n) + x == n + x
var yr = yearlyResults[co];
yr.OptTotalDos = (yr.OptTotalDos ?? 0f) + (float)optResultYear.OptTotalDos;
yr.OptDos1 = (yr.OptDos1 ?? 0f) + (float)optResultYear.OptDos1;
yr.OptDos2 = (yr.OptDos2 ?? 0f) + (float)optResultYear.OptDos2;
yr.OptCost = (yr.OptCost ?? 0f) + (float)optResultYear.OptCost;
yr.OptProductie = (yr.OptProductie ?? 0f) + (float)optResultYear.OptProductie;
var yrCOo2 = yearlyResultsCO2[co];
yrCOo2.OptConcLp = (yrCOo2.OptConcLp ?? 0f) + (float)optResultYear.OptConcLp;
yrCOo2.Datum = date;
Я предполагаю, что словарные записи относятся к типу класса (т. е. ссылочному типу). Тогда вы сможете получить доступ к словарю только один раз, присвоив записи временной переменной: var yr = yearlyResults[co];.
Вы должны быть осторожны со структурами, поскольку словарь вернет вам их копию вместо ссылки. Если бы это была структура, вам пришлось бы снова вставить ее в словарь в конце: yearlyResults[co] = yr;
Почему вы используете «+ = "? Нуль плюс значение — это ноль.