我有一个方法可以计算db中每个月的总金额,如图所示。
public static List<Sale> ChartMonthlySalePerYear()
{
using (SQLiteConnection con = new SQLiteConnection(Connection.DatabaseLocationString))
{
SQLiteCommand cmd = null;
string query = String.Format("SELECT strftime('%m', SaleDate) AS month, SUM(AmountPaid) AS sum_amountpaid FROM {0} WHERE strftime('%Y', SaleDate) = @1 GROUP BY strftime('%m', SaleDate) ", Sale.TABLE_NAME);
cmd = new SQLiteCommand(query, con);
cmd.Parameters.Add(new SQLiteParameter("@1", Properties.Settings.Default.ChartYearlyDisplay));
con.Open();
SQLiteDataReader reader = cmd.ExecuteReader();
var list = new List<Sale>();
while (reader.Read())
{
Sale value = new Sale()
{
Months = reader["month"].ToString(),
SUMAmountPaid = Convert.ToDecimal(reader["sum_amountpaid"])
};
list.Add(value);
}
con.Close();
return list;
}
}
它会按月返回一个像这样的列表,
这就是使用方法的地方。
List<Sale> sum = SaleViewModel.ChartMonthlySalePerYear();
Jan = sum[0].SUMAmountPaid;
Feb = sum[1].SUMAmountPaid;
Mar = sum[2].SUMAmountPaid;
Apr = sum[3].SUMAmountPaid;
May = sum[4].SUMAmountPaid;
Jun = sum[5].SUMAmountPaid;
Jul = sum[6].SUMAmountPaid;
//For Ausgust
if (sum[7] != null)
Aug = 0;
else
Aug = sum[7].SUMAmountPaid;
//For September
if (sum[7] != null)
Sep = 0;
else
Sep = sum[7].SUMAmountPaid;
我现在的挑战是,8月和8月没有任何价值。 9月,我想在我给它一个默认值之前先检查,但它抛出一个异常。 Index was out of range. Must be non-negative and less than the size of the collection.
八月&amp;九月
提前谢谢。
答案 0 :(得分:6)
您希望在访问该索引之前检查索引是否小于或等于列表的长度,以避免索引超出范围异常:
if (sum.Count <= 7)
Aug = 0;
else
Aug = sum[7].SUMAmountPaid;
但如果您的数据存在漏洞,那么这项工作就像您期望的那样。如果您在数据中有漏洞,则列表的索引不会与月份匹配。如果是这种情况,请考虑使用Dictionary<int, Sale>()
:
var salesByMonth = new Dictionary<int, Sale>();
while (reader.Read())
{
Sale value = new Sale()
{
Months = reader["month"].ToString(),
SUMAmountPaid = Convert.ToDecimal(reader["sum_amountpaid"])
};
salesByMonth.Add(int.Parse(value.Months), value);
}
并且
Sale value;
if (salesByMonth.TryGetValue(1, out value))
Jan = value.SUMAmountPaid;
else
Jan = 0;
if (salesByMonth.TryGetValue(2, out value))
Feb = value.SUMAmountPaid;
else
Feb = 0;
答案 1 :(得分:0)
您不应该对此使用索引方法,因为您的Sale
类型具有Months
属性,其中填充了reader["month"]
值。您可以使用谓词(Func<Sale, bool>
委托)确定是否存在月份。
使用Linq,您可以将谓词与First
或FirstOrDefault
一起使用,以返回评估为true
的第一个实例。
List<Sale> sum = SaleViewModel.ChartMonthlySalePerYear();
Jan = sum.Where((item) => item.Months == 1).Select((item) => item.SUMAmountPaid).DefaultIfEmpty(0).First();
Feb = sum.Where((item) => item.Months == 2).Select((item) => item.SUMAmountPaid).DefaultIfEmpty(0).First();
Mar = sum.Where((item) => item.Months == 3).Select((item) => item.SUMAmountPaid).DefaultIfEmpty(0).First();
Mar = sum.Where((item) => item.Months == 4).Select((item) => item.SUMAmountPaid).DefaultIfEmpty(0).First();
,或者
Jan = sum.Any((item) => item.Months == 1) ? sum.First((item) => item.Months == 1).SUMAmountPaid : 0;
Feb = sum.Any((item) => item.Months == 2) ? sum.First((item) => item.Months == 2).SUMAmountPaid : 0;
Mar = sum.Any((item) => item.Months == 3) ? sum.First((item) => item.Months == 3).SUMAmountPaid : 0;
Apr = sum.Any((item) => item.Months == 4) ? sum.First((item) => item.Months == 4).SUMAmountPaid : 0;
你可以.ForEach
遍历你的记录和一个切换案例来映射它们。
List<Sale> sum = SaleViewModel.ChartMonthlySalePerYear()
.ForEach((item) => {
switch(item.Months)
{
case 1:
Jan = item.SUMAmountPaid;
break;
case 2:
Feb = item.SUMAmountPaid;
break;
case 3:
Mar = item.SUMAmountPaid;
break;
case 4:
Apr = item.SUMAmountPaid;
break;
case 5:
May = item.SUMAmountPaid;
break;
case 6:
Jun = item.SUMAmountPaid;
break;
case 7:
Jul = item.SUMAmountPaid;
break;
case 8:
Aug = item.SUMAmountPaid;
break;
case 9:
Sept = item.SUMAmountPaid;
break;
case 10:
Oct = item.SUMAmountPaid;
break;
case 11:
Nov = item.SUMAmountPaid;
break;
case 12:
Dec = item.SUMAmountPaid;
break;
default: //do nothing
break;
}
});
默认情况下确保Jan
到Dec
为0
。