Chart from multiple tables - c#

I have three tables named Deposit, Debit and Transfer,
like
Deposit { DepositID, DepostDate, Amount}
Debit { DebitID, DebitDate, Amount}
Transfer { TransferID, TransferDate, Amount}
How can I show all three tables in one chart? I am even wondering if it is better to put those three tables into one table instead, like
Transaction {TransactionId, TransactionTypeId, TransactionDate, Amount}
where TransactiontypeId could be 1 = for Deposit, 2 for Debit and 3 for Transfer and bind this transaction table to the chart.
Let's say I have all those in one table instead and with table name Transactions then #mm8 helped me figure this out:
var result = (from pr in db.Transactions
join tr in db.TransactionType on pr.TrTypeId equals tr.TransactionTypeId
select new
{
TransactionDate = pr.TransactionDate,
TransactionType = tr.TrType,
Amount = pr.Amount
}).ToList();
chart1.DataSource = result
.GroupBy(x => x.TransactionDate.Value.Year)
.Select(g => new
{
Year = g.Key,
TransactionType = g. //////
Amount = g.Sum(y => y.Amount)
})
.ToArray();
Is is better to have a chart from one table or from multiple tables and how to do multiple.
I am aware that I have to create different series for every table like this:
var Depseries = chart1.Series.Add("Deposit");
Depseries.XValueMember = "Year";
Depseries.YValueMembers = "DepositAmount";
Depseries.Name = "Deposit";
chart1.ChartAreas["ChartArea1"].AxisX.Interval = 1;
chart1.Series["Deposit"].IsValueShownAsLabel = true;
Depseries.CustomProperties = "LabelStyle=Left";
// Debit
var Debseries = chart1.Series.Add("Debit");
Debseries.XValueMember = "Year";
Debseries.YValueMembers = "DebitAmount";
Debseries.Name = "Debit";
chart1.ChartAreas["ChartArea1"].AxisX.Interval = 1;
chart1.Series["Debit"].IsValueShownAsLabel = true;
Debseries.CustomProperties = "LabelStyle=Left";
// Transfer
var FDseries = chart1.Series.Add("Transfer");
FDseries.XValueMember = "Year";
FDseries.YValueMembers = "TransferAmount";
FDseries.Name = "Transfer";
chart1.ChartAreas["ChartArea1"].AxisX.Interval = 1;
chart1.Series["Transfer"].IsValueShownAsLabel = true;
FDseries.CustomProperties = "LabelStyle=Left";

You could just select the data from each of the tables and then use the DataBind method to populate the series with data, e.g.:
var deposits = (from x in db.Deposits select new { x.DepositDate, x.Amount })
.ToArray()
.GroupBy(x => x.DepositDate.Year)
.Select(g => new { Year = g.Key, Amount = g.Sum(y => y.Amount) })
.ToArray();
var Depseries = chart1.Series.Add("Deposit");
Depseries.XValueMember = "Year";
Depseries.YValueMembers = "DepositAmount";
Depseries.Name = "Deposit";
chart1.ChartAreas["ChartArea1"].AxisX.Interval = 1;
chart1.Series["Deposit"].IsValueShownAsLabel = true;
Depseries.CustomProperties = "LabelStyle=Left";
chart1.Series["Deposit"].Points.DataBind(deposits, "Year", "Amount", null);
var debits = (from x in db.Debits select new { x.DebitDate, x.Amount })
.ToArray()
.GroupBy(x => x.DebitDate.Year)
.Select(g => new { Year = g.Key, Amount = g.Sum(y => y.Amount) })
.ToArray();
var Debseries = chart1.Series.Add("Debit");
Debseries.XValueMember = "Year";
Debseries.YValueMembers = "DebitAmount";
Debseries.Name = "Debit";
chart1.ChartAreas["ChartArea1"].AxisX.Interval = 1;
chart1.Series["Debit"].IsValueShownAsLabel = true;
Debseries.CustomProperties = "LabelStyle=Left";
chart1.Series["Debit"].Points.DataBind(debits, "Year", "Amount", null);
...

Related

Loop through 2 grouped object lists & add them in an observable collection C#

I have these two grouped object lists which I grouped like this:
var q = it
.AsQueryable()
.GroupBy(x => x.date)
.Select(g => new
{
Date = g.Key,
Details = g.Select(x => new
{
Name = x.name,
Price = x.price,
Trans = x.trans,
})
.ToList()
})
.ToList();
var q4 = t
.AsQueryable()
.GroupBy(x => x.date)
.Select(g => new
{
Date = g.Key,
Details = g.Select(x => new
{
Location = x.location,
Points = x.points,
Pos = x.position,
Time = x.time,
Discount = x._discount,
Totals = x._total,
Trans = x.trans,
Ref = x.refer
})
.ToList()
});
What I want to do is looped through these lists and add their respective contents together in a new observable collection, like this:
Transactions = new ObservableCollection<Transaction>();
Transactions.Add(new Transaction
{
Details = "Date: " + obj.Date,
TransDet = "Time: " + k.Time + " | Reference: " + k.Ref(etc),
ItemDet = obj.Name,
obj.Price,
obj.Trans,
Isvisible = false
});
The two lists use the Date as the common factor that links them - is there a way to loop through both of them and put their contents into this new observable collection underneath the key date?
Thank you!

C# group by list then SUM

How to group by then sum inside the list
below is my sample code:
List<BrandType> brandTypeList = new List<BrandType>();
BrandType brandTypeClass = new BrandType();
brandTypeClass.Amount = 100;
brandTypeClass.Count = 50;
brandTypeClass.Category = "Fish";
brandTypeList.Add(brandTypeClass);
BrandType brandTypeClass2 = new BrandType();
brandTypeClass2.Amount = 100;
brandTypeClass2.Count = 50;
brandTypeClass2.Category = "Fish";
brandTypeList.Add(brandTypeClass2);
BrandType brandTypeClass3 = new BrandType();
brandTypeClass3.Amount = 100;
brandTypeClass3.Count = 50;
brandTypeClass3.Category = "Pork";
brandTypeList.Add(brandTypeClass3);
brandTypeList.GroupBy(x => new { x.Category }).Select
(x => new { Category = x.Key.Category,
Amount = x.Sum(z => z.Amount),
Count = x.Sum(z => z.Count) });
Here's what it looks like
[0] {Amount = 100, Category = "Pork", Count = 50}
[1] {Amount = 100, Category = "Fish", Count = 50}
[2] {Amount = 100, Category = "Fish", Count = 50}
How can I SUM the amout and count then group by Category?
I want the result to be
Amount = 200, Category = "Fish", Count = 100
Amount = 100, Category = "Pork" Count = 50
The following code snippet will work for you:
var result = from brand in brandTypeList
group brand by brand.Category into grp
select new
{
Category = grp.Key,
Amount = grp.Sum(z => z.Amount),
Count = grp.Sum(z => z.Count)
};
This one also works fine:
var result = brandTypeList.GroupBy(x => x.Category).Select
(y => new {
Category = y.Key,
Amount = y.Sum(z => z.Amount),
Count = y.Sum(z => z.Count)
});
It turns out that your code also works fine, probably the problem is that you expect list to be modified inplace, but linq does not produce side effects and new IEnumerable will be created and you need to save results to variable.

Linq Include Extra Column in GroupBy Selection

I have a "ReactionSimple" column that I'd like to include in the GroupBy selection but when I include it in the Group By it throws off the returned row count in a big way. Is there a way to include the commented out column in the final grouped selection without throwing off the result count. I'm a LINQ noob.
var reactivityResults = new List<ReactivityResultViewModel>();
var reactivityResults2 = new List<ReactivityResultViewModel>();
var classifications = GetMaterialClassifications(test.TestType);
var antigens = _db.Antigens.ToList();
if (test.ResultSets.Any())
{
var testResult = test.ResultSets.FirstOrDefault();
var dateReported = testResult.DateReported;
var details = testResult.ResultSetDetails.ToList();
if (details.Any())
{
reactivityResults = (from d in details
join a in _db.Antigens on d.AntigenId equals a.AntigenId
join ma in _db.MaterialAntigens on a.AntigenId equals ma.AntigenId
join md in _db.MaterialDefs on ma.MaterialDefId equals md.MaterialDefId
join c in classifications on md.MaterialId equals c.MaterialId
select new ReactivityResultViewModel
{
MaterialId = c.MaterialId,
MaterialName = c.MaterialName,
IsActive = md.IsActive,
ReactionSimple = (ReactionTypeEnum)d.ReactionSimple,
TestId = test.TestId,
AccessionId = test.AccessionId,
PatientFirstName = test.Patient.Party.NameFirst,
PatientLastName = test.Patient.Party.NameLast,
TestType = (TestTypeNoFlagsEnum)test.TestType,
DateReported = dateReported,
ManufacturerId = c.ManufacturerId,
ManufacturerName = c.ManufacturerName
})
.OrderBy(x => x.MaterialName)
.ToList();
var sreactivityResults2 = reactivityResults
.GroupBy(x => new {
x.MaterialId, x.AccessionId, x.DateReported,
x.IsActive, x.ManufacturerId, x.ManufacturerName,
x.MaterialName, x.PatientFirstName, x.PatientLastName,
x.TestId, x.TestType,
//x.ReactionSimple
})
.Select(x => new ReactivityResultViewModel
{
MaterialId = x.Key.MaterialId,
MaterialName = x.Key.MaterialName,
IsActive = x.Key.IsActive,
//ReactionSimple = x.Key.ReactionSimple,
TestId = test.TestId,
AccessionId = test.AccessionId,
PatientFirstName = test.Patient.Party.NameFirst,
PatientLastName = test.Patient.Party.NameLast,
TestType = (TestTypeNoFlagsEnum)test.TestType,
DateReported = dateReported,
ManufacturerId = x.Key.ManufacturerId,
ManufacturerName = x.Key.ManufacturerName
})
.ToList();
var sd2 = sreactivityResults2.ToList();
}
return reactivityResults;

Code Coming up blank every time

I have this code and it is supposed to fill up the appropriate tables and it is filling the first table (Mu_Reports) one but the second table (MU_By_Machine) keeps coming up blank
using (var db = new ProductionContext())
{
var objct = ((System.Data.Entity.Infrastructure.IObjectContextAdapter)db).ObjectContext;
objct.ExecuteStoreCommand("TRUNCATE TABLE [MU Report]");
objct.ExecuteStoreCommand("TRUNCATE TABLE [MU By Machine]");
db.SaveChanges();
var query = db.Production_Reports
.GroupBy(x => new { x.Date, x.Machine_Number, x.Shift })
.Select(x => new
{
Date = x.Key.Date,
Shift = x.Key.Shift,
MachineNum = x.Key.Machine_Number,
MU = x.Sum(i => i.Partial_MU_ * 100)
}).ToList();
foreach (var item in query)
{
var z = new MU_Report();
z.Date = System.Convert.ToDateTime(item.Date);
z.Shift = item.Shift;
z.Machine_Number = item.MachineNum;
z.MU = item.MU;
db.MU_Reports.Add(z);
db.SaveChanges();
}
var query2 = from b in db.MU_Reports
join downtime in db.Downtime_Reports on b.Shift equals downtime.Shift
where downtime.Downtime_Code.Equals("9185")
group downtime by new { b.Date, b.Shift, b.Machine_Number, b.MU } into g
select new
{
Date = g.Key.Date,
Shift = g.Key.Shift,
Machine = g.Key.Machine_Number,
MU = g.Key.MU,
No_Work_Hours = g.Sum(x => x.Total_DownTime)
};
foreach (var item in query2)
{
var y = new MU_By_Machine();
y.Date = item.Date;
y.Shift = item.Shift;
y.Machine_Number = item.Machine;
y.MU = item.MU;
y.MU_w_o_No_Work = (item.MU * 8) / (8 - item.No_Work_Hours);
db.MU_By_Machines.Add(y);
db.SaveChanges();
}
}
I don't know if it is because I cannot have query and query2 go in the same button or if I am just doing something wrong. No error occurs only MU_By_Machine appears blank. Please keep in mind I'm new to C#.
You will need to invoke .ToList() at the end of your select statement in query2 as well.

LINQ find max/min value with corresponding time fields

I have a table of data recordings from a weather station from which I am querying results into a WPF ListBox.
The table structure is:
date
time
temp
rain_today
humidity
etc
I have a query which works fine:
var q = from c in db.Apr11log
group c by c.LogDate into g
orderby g.Key
select new
{
LogDate = g.Key,
MaxTemp = g.Max(c => c.Temp),
MinTemp = g.Min(c => c.Temp),
Rain = g.Max(c => c.Rain_today),
};
However I am trying to get the corresponding time of the Max Temp and Min Temp, i.e.
TimeMax = .....
TimeMin = .....
I've googled and googled but found nothing useful.
var q = from c in db.Apr11log
group c by c.LogDate into g
orderby g.Key
select new
{
LogDate = g.Key,
MaxRow = g.OrderByDescending(c => c.Temp).Select(c => new { c.LogDate, c.Temp }).First(),
MinRow = g.OrderBy(c => c.Temp).Select(c => new { c.LogDate, c.Temp }).First(),
Rain = g.Max(c => c.Rain_today),
};
or
var q = from c in db.Apr11log
group c by c.LogDate into g
orderby g.Key
let maxRow = g.OrderByDescending(c => c.Temp).First()
let minRow = g.OrderBy(c => c.Temp).First()
select new
{
LogDate = g.Key,
MaxTemp = maxRow.Temp,
MaxTempDate = maxRow.LogDate,
MinTemp = minRow.Temp,
MinTempDate = minRow.LogDate,
Rain = g.Max(c => c.Rain_today),
};
let maxTemp = c.Max(c=>c.Temp)
let minTemp = c.Min(c=>c.Temp)
select new {
LogDate = g.Key,
MaxTemp = maxTemp,
MinTemp = minTemp,
MaxTime = g.FirstOrDefault(c=>c.Temp = maxTemp).Time,
MinTime = g.FirstOrDefault(c => c.Temp = minTemp).Time,
Rain = g.Max(c => c.Rain_today),
};

Categories