Is there a way to check if the sum of PREM_A or PREM_B is not 0 in the same LINQ query and not in a separate LINQ query like the one below i.e. matchRows?
var resultsDt = dt.AsEnumerable().GroupBy(row => new
{
Id = row.Field<string>("ID")
}).Select(grp =>
{
DataRow newRow = dt.NewRow();
newRow["ID"] = grp.Key.Id.Trim();
newRow["PREM_A"] = grp.Sum(r => r.Field<decimal>("PREM_A"));
newRow["PREM_B"] = grp.Sum(r => r.Field<decimal>("PREM_B"));
return newRow;
}).CopyToDataTable();
var matchRows = resultsDt.Select().Where(x => x.Field<decimal>("PREM_A") != 0 || x.Field<decimal>("PREM_B") != 0);
foreach (DataRow row in matchRows)
{
//do something
}
You don't need to convert to a data table for every step, it would be easier to query if you moved away from that.
var query =
from row in dt.AsEnumerable()
group new
{
premA = row.Field<decimal>("PREM_A"),
premB = row.Field<decimal>("PREM_B"),
} by row.Field<string>("ID").Trim() into g
let premA = g.Sum(x => x.premA)
let premB = g.Sum(x => x.premB)
where premA != 0M || premB != 0M
select new
{
Id = g.Key,
PremA = premA,
PremB = premB,
};
Also:
var resultsDt = dt.AsEnumerable()
.GroupBy(row => row.Field<string>("ID"))
.Select(grp =>new {Id= grp.Key,
PREM_A= grp.Sum(r => r.Field<decimal>("PREM_A")),
PREM_B=grp.Sum(r => r.Field<decimal>("PREM_B"))
})
.Where(e=>e.PREM_A!=0 || e.PREM_B!=0);
Related
I want add a new column to find which is lasted record in group.
Can I write subquery in Select() method?
I have try this
var test = DailyPeriods.Where(x => x.BookingDate == "2016/12/30")
.Select(x =>
new
{
PERIOD_GROUP_ID = x.PeriodGroupID,
PERIOD_NAME = x.PeriodName,
New_Column = DailyPeriods
.Where(z => z.BookingDate == "2016/12/30")
.Select(a =>
new
{
PeriodGroupID = a.PeriodGroupID,
period_name = a.PeriodName
}
)
.GroupBy(b => b.period_name)
.Select(g => g.Last().PeriodGroupID)
.Contains(x.PeriodName)
})
But will occur this error
"column not in scope: A:2211708.C(BOOKING_DATE)"
Try this..
var lastRecords = periodList.GroupBy(l => l.PeriodName)
.Select(x => new { PeriodName = x.Key,
PeriodGroupId = x.OrderBy(l => l.PeriodGroupId).Last().PeriodGroupId});
var result = from period in periodList
from lastRec in lastRecords.Where(r => r.PeriodGroupId == period.PeriodGroupId
&& r.PeriodName == period.PeriodName)
.DefaultIfEmpty()
select new { period.PeriodGroupId,period.PeriodName, New_Column=lastRec==null?false:true };
I want to order my Linq GroupBy statement but the item that has the more Total Descending but i can't make it
This is my LinQ
foreach (var item in db
.Pos.Where(r => r.Fecha.Day <= today.Day)
.Select(g => new { Pdv = g.Pdv, Total = g.Total })
.GroupBy(l => l.Pdv)
.AsEnumerable()
.Select(z => new {
Punto_De_Venta=z.Key,
Total = String.Format("{0:$#,##0.00;($#,##0.00);Zero}",
Decimal.Round(z.Sum(l => l.Total), 0))
}))
{
listadepuntos.Add(item.ToString());
}
var grupoPdv = new SelectList(listadepuntos.ToList());
ViewBag.GroupS = grupoPdv;
The Out put of my Linq Statement is :
Punto_De_Venta = Central, Total = 42,143.00
Punto_De_Venta = Restaurante, Total = 189,949.00
Punto_De_Venta = Venta Moto, Total = 89,678.00
And the Output im looking for is:
Punto_De_Venta = Restaurante, Total = 189,949.00
Punto_De_Venta = Venta Moto, Total = 89,678.00
Punto_De_Venta = Central, Total = 42,143.00
How can i do this?? i cant find a way to make this
The List<> does guarantee ordering, sort the List before passing to your SelectList
var grupoPdv = new SelectList(listadepuntos.OrderByDescending(l=>l.Total).ToList());
ViewBag.GroupS = grupoPdv;
Another approach :
Modify source query to return a sorted list.
var results = db.Pos.Where(r => r.Fecha.Day <= today.Day)
.Select(g => new { Pdv = g.Pdv, Total = g.Total })
.GroupBy(l => l.Pdv).AsEnumerable()
.Select(z => new { Punto_De_Venta=z.Key, Total = String.Format("{0:$#,##0.00;($#,##0.00);Zero}", Decimal.Round(z.Sum(l => Total), 0))})
.OrderByDescending(l=>l.Total)
.ToList();
Once you get the sorted list you can create your SelectList with sorted result.
var grupoPdv = new SelectList(result);
ViewBag.GroupS = grupoPdv;
You'll need to do something like this:
foreach (var item in db.Pos.Where(r => r.Fecha.Day <= today.Day)
.Select(g => new { Pdv = g.Pdv, Total = g.Total })
.GroupBy(l => l.Pdv)
.AsEnumerable()
.Select(z => new { Punto_De_Venta = z.Key, Total = z.Sum(l => l.Total) })
.OrderByDescending(r => r.Total)
.Select(r => new { Punto_De_Venta = r.Punto_De_Venta, Total = String.Format("{0:$#,##0.00;($#,##0.00);Zero}", Decimal.Round(z.Sum(l => l.Total), 0))})
{
listadepuntos.Add(item.ToString());
}
I have this Linq to Entity:
var sitesGrpByClientAndFreq = from cfr in clientFullReview2
group cfr by new { cfr.inspectionFreqvency } into g
select new
{
inspectionFreqvency = g.Key.inspectionFreqvency,
siteCount = g.Select(x => x.siteId).ToArray().Distinct().Count(),
normalSitesCount = g.Where(x => x.isNormal == true).Select(x=>x.isNormal).ToArray().Count(),
}
From the above linq I get this result:
My question is How can I remove all rows where inspectionFrequency = -1?
You can mix and match the let keyword with where. It could be something like:
var sitesGrpByClientAndFreq =
from cfr in clientFullReview2
group cfr by new { cfr.inspectionFreqvency } into g
let inspectionFreqvency = g.Key.inspectionFreqvency
where inspectionFreqvency != -1
select new
{
inspectionFreqvency = inspectionFreqvency,
siteCount = g.Select(x => x.siteId).ToArray().Distinct().Count(),
normalSitesCount = g.Where(x => x.isNormal == true).Select(x=>x.isNormal).ToArray().Count(),
}
I would like to do a group by and on that a sum and a count. I don't seem to be able to create the solution in linq. How can I convert my query to linq?
SELECT HistoricalBillingProductGroup,
COUNT(*),
BillingPeriod,
SUM(TotalMonthlyChargesOtcAndMrc)
FROM [x].[dbo].[tblReport]
group by BillingPeriod, HistoricalBillingProductGroup
order by BillingPeriod
This is what I got sofar in Linq
var result =
context.Reports.GroupBy(x => new {x.BillingPeriod, x.HistoricalBillingProductGroup})
.Select(x => new StatisticsReportLine
{
HistoricalBillingGroup = x.FirstOrDefault().HistoricalBillingProductGroup,
BillingPeriod = x.FirstOrDefault().BillingPeriod,
CountOfRows = x.Count(),
SumOfAmount = x.Sum(p => p.TotalMonthlyChargesOtcAndMrc) ?? 0
})
.ToString();
The query I get from this is enormous and takes a very long time to load. In SQL its a matter of milliseconds. I hardly doubt this is the solution.
I believe the calls to x.FirstOrDefault() are the source of your problem. Each one of these will result in a very costly inner query inside the SELECT clause of the generated SQL.
Try using the Key property of the IGrouping<T> instead :
var result = context.Reports
.GroupBy(x => new {x.BillingPeriod, x.HistoricalBillingProductGroup})
.OrderBy(x => x.Key.BillingPeriod)
.Select(x => new StatisticsReportLine
{
HistoricalBillingProductGroup = x.Key.HistoricalBillingProductGroup,
BillingPeriod = x.Key.BillingPeriod,
CountOfRows = x.Count(),
SumOfAmount = x.Sum(p => p.TotalMonthlyChargesOtcAndMrc) ?? 0
});
Or if you prefer query syntax:
var result =
(from r in context.Reports
group r by new { r.BillingPeriod, r.HistoricalBillingProductGroup } into g
orderby g.Key.BillingPeriod
select new StatisticsReportLine
{
HistoricalBillingProductGroup = g.Key.HistoricalBillingProductGroup,
BillingPeriod = g.Key.BillingPeriod,
CountOfRows = g.Count(),
SumOfAmount = x.Sum(p => p.TotalMonthlyChargesOtcAndMrc) ?? 0
});
You could try this one:
var result = context.Reports
.GroupBy(x => new {x.BillingPeriod, x.HistoricalBillingProductGroup})
.Select(x => new StatisticsReportLine
{
HistoricalBillingGroup = x.Key.HistoricalBillingProductGroup,
BillingPeriod = x.Key.BillingPeriod,
CountOfRows = x.Count(),
SumOfAmount = x.Sum(p => p.TotalMonthlyChargesOtcAndMrc) ?? 0
}).ToString();
In the above query you make a group by on two properties, BillingPeriod and HistoricalBillingProductGroup. So in each group that will be created, you will have a key, that will be consisted by these two properties.
I'm trying to translate this sql statement
SELECT row, SUM(value) as VarSum, AVG(value) as VarAve, COUNT(value) as TotalCount
FROM MDNumeric
WHERE collectionid = 6 and varname in ('C3INEV1', 'C3INEVA2', 'C3INEVA3', 'C3INVA11', 'C3INVA17', 'C3INVA19')
GROUP BY row
into an EF 4 query using lambda expressions and am missing something.
I have:
sumvars = sv.staticvararraylist.Split(',');
var aavresult = _myIFR.MDNumerics
.Where(r => r.collectionid == _collid)
.Where(r => sumvars.Contains(r.varname))
.GroupBy(r1 =>r1.row)
.Select(rg =>
new
{
Row = rg.Key,
VarSum = rg.Sum(p => p.value),
VarAve = rg.Average(p => p.value),
TotalCount = rg.Count()
});
where the staticvararraylist has the string 'C3INEV1', 'C3INEVA2', 'C3INEVA3', 'C3INVA11', 'C3INVA17', 'C3INVA19' (without single quotes) and the _collid variable = 6.
While I'm getting the correct grouping, my sum, average, & count values aren't correct.
You didn't post your error message, but I suspect it's related to Contains. I've found that Any works just as well.
This should get you quite close:
var result =
from i in _myIFR.MDNumerics
where i.collectionid == _collid && sumvars.Any(v => i.varname == v)
group i by i.row into g
select new {
row = g.Key,
VarSum = g.Sum(p => p.value),
VarAve = g.Average(p => p.value),
TotalCount = g.Count()
};
Try this:
var aavresult = _myIFR.MDNumerics
.Where(r => r.collectionid == _collid && sumvars.Contains(r.varname))
.GroupBy(r1 =>r1.row,
(key,res) => new
{
Row = key,
VarSum = res.Sum(r1 => r1.value),
VarAve = res.Average(r1 => r1.value),
TotalCount = res.Count()
});