Multiple values โโfor one key
I have a list containing categories and their acceptance / rejection counts, but there is a problem with this list. I am using LINQ query to access data and I have grouped them by category name and in Accept / Reject (ResultCode) code. Thus, the data is in this form:
Almost all categories have both AP counts and RJ counts. And what I'm trying to do is show that each category accepts and rejects an invoice. What should I use? Hashtables don't fit into this problem, I tried a dictionary with int List as value but couldn't add when the same key came up.
UPDATE
List<ModReportingDM.ReportObjects.AllCategories> allcats = new List<ModReportingDM.ReportObjects.AllCategories>();
Dictionary<string, ModReportingDM.ReportObjects.ResultCode> dict = new Dictionary<string, ModReportingDM.ReportObjects.ResultCode>();
ModReportingDM.ReportObjects.ResultCode x = new ModReportingDM.ReportObjects.ResultCode();
allcats = reportBLL.GetAllCats(model.ModId, model.ReportStartDate, model.ReportEndDate);
if (allcats != null)
{
model.AllCatsList = new List<ModReportingDM.ReportObjects.AllCategories>();
foreach (var item in allcats)
{
x.Accepted = item.Count;
x.Rejected = item.Count;
dict.Add(item.Category, x);
}
}
Query:
public List<AllCategories> GetAllCats(int modId, DateTime startDate, DateTime endDate)
{
using (entities = new ModReportingEntities())
{
var query = (from c in entities.Content
where c.ModId == modId && c.CreatedTime >= startDate && c.CreatedTime <= endDate && c.Category != null
group c by new { c.Category, c.ResultCode } into g
orderby g.Count() ascending
select new AllCategories
{
Category = g.Key.Category,
ResultCode = g.Key.ResultCode,
AcceptCount = g.Count(),
RejectCount = g.Count()
});
return query.ToList();
}
}
source to share
My colleague and I realized that we can track a category, and if the same category happens, it means that only its field (either AcceptCount or RejectCount) needs to be changed. So, we created a lambda expression like this:
foreach(var item in allcats)
{
if (model.AllCategories.Select(m => m).Where(x => x.Category == item.Category).ToList().Count == 0)
{
if (item.ResultCode == "AP") {
model.AllCategories.Add(new ModReportingDM.ReportObjects.AllCategories()
{
Category = item.Category,
AcceptCount = item.Count
});
}
else
{
model.AllCategories.Add(new ModReportingDM.ReportObjects.AllCategories()
{
Category = item.Category,
RejectCount = item.Count
});
}
}
else
{
ModReportingDM.ReportObjects.AllCategories x = model.AllCategories.Select(n => n).Where(y => y.Category == item.Category).ToList().First();
if (item.ResultCode == "AP")
{
x.AcceptCount = item.Count;
}
else
{
x.RejectCount = item.Count;
}
}
}
If the same category happens, go ahead and change its AcceptCount or RejectCount accordingly. This is how I solved the problem.
source to share
What I would do is create a class ResultCode
:
public class ResultCode
{
public int Ap { get; set; }
public int Rj { get; set; }
}
and then use Dictionary<string, ResultCode>
that maps each category to your report.
You can also take a different approach, using Tuple<T1, T2>
(which I personally don't like) that simply maps your key to two different values:
Dictionary<string, Tuple<int, int>> categoryToResultCode;
source to share
List<Tuple<string, string, int>> listOfTuples = new List<Tuple<string, string, int>>();
Tuple<string, string, int> tupleItem1 = new Tuple<string, string, int>("A", "AP", 1);
listOfTuples.Add(tupleItem1);
You can use Tuple. Please refer to http://msdn.microsoft.com/en-us/library/system.tuple%28v=vs.110%29.aspx
source to share