Im using ASP MVC, I have this LINQ to get employees DTR:
IEnumerable<DatatablesViewModel> viewmodel =
(from a in db.tHREmployees
join b in db.tTADTRs on a.EmpID equals b.EmpID
join c in db.tHRJobGrades on a.JobGrdID equals c.JobGrdID
join d in db.tTAShifts on b.ShftID equals d.ShftID
join e in db.tTADays on b.DayID equals e.DayID
where (b.LogDt >= PeriodDates.FromDt && b.LogDt <= PeriodDates.ToDt)
select new DatatablesViewModel
{
EmpID = a.EmpID,
Name = a.LastNm + ", " + a.FirstNm + ", " + a.MiddleNm,
JobGradeDesc = c.JobGrdDesc,
ShftNm = d.ShftNm,
DayType = e.DayNm,
LogDT = b.LogDt,
LogIn = b.LogIn,
LogOut = b.LogOut,
Absent = b.AbsDay,
Work = b.WorkHr,
Late = b.LateHr,
Overtime = b.OTHr,
Undertime = b.OTHr,
Nightdiff = b.NDHr,
NightPrem = b.NPHr,
ApprovedOT = b.AppOT,
ApprovedOB = b.AppOB,
ApprovedCoa = b.AppCOA,
ApprovedCs = b.AppCS,
Exception = b.ExcptStatus
}).OrderBy(x => x.EmpID);
In my view i have dropdown menu that has employee names with 'ALL' option.
I want to add a condition inside 'where' in above code somthing like:
if(parameter.selectedEmp != "ALL"){
Where(x => x.EmpID == param.CustomParam_EmpID) <-- add this filter
}
I want to select only what is needed in my query to avoid delay.
You don't need to add it in the Where clause directly. The IEnumerable and your LINQ query are only evaluated once you start to iterate through the collection. You could simply do something like this:
var relevantVMObjects =
(from a in db.tHREmployees
join b in db.tTADTRs on a.EmpID equals b.EmpID
join c in db.tHRJobGrades on a.JobGrdID equals c.JobGrdID
join d in db.tTAShifts on b.ShftID equals d.ShftID
join e in db.tTADays on b.DayID equals e.DayID
where (b.LogDt >= PeriodDates.FromDt && b.LogDt <= PeriodDates.ToDt)
select new DatatablesViewModel
{
EmpID = a.EmpID,
Name = a.LastNm + ", " + a.FirstNm + ", " + a.MiddleNm,
JobGradeDesc = c.JobGrdDesc,
ShftNm = d.ShftNm,
DayType = e.DayNm,
LogDT = b.LogDt,
LogIn = b.LogIn,
LogOut = b.LogOut,
Absent = b.AbsDay,
Work = b.WorkHr,
Late = b.LateHr,
Overtime = b.OTHr,
Undertime = b.OTHr,
Nightdiff = b.NDHr,
NightPrem = b.NPHr,
ApprovedOT = b.AppOT,
ApprovedOB = b.AppOB,
ApprovedCoa = b.AppCOA,
ApprovedCs = b.AppCS,
Exception = b.ExcptStatus
}).OrderBy(x => x.EmpID);
if(parameter.selectedEmp != "ALL")
relevantVMObjects = relevantVMObjects.Where(x => x.EmpID == param.CustomParam_EmpID);
IEnumerable<DatatablesViewModel> viewmodel = relevantVMObjects;
You can do this by OR condition
string selectedEmp=parameter.selectedEmp;
IEnumerable<DatatablesViewModel> viewmodel =
(from a in db.tHREmployees
join b in db.tTADTRs on a.EmpID equals b.EmpID
join c in db.tHRJobGrades on a.JobGrdID equals c.JobGrdID
join d in db.tTAShifts on b.ShftID equals d.ShftID
join e in db.tTADays on b.DayID equals e.DayID
where (b.LogDt >= PeriodDates.FromDt && b.LogDt <= PeriodDates.ToDt) &&
(selectedEmp != "ALL" || a.EmpID == param.CustomParam_EmpID)
select new DatatablesViewModel
{
...
}
Related
I'm trying to convert this to LINQ C#. I am expecting a single result with the most recent data but the LINQ returns 3 results with the individual data.
SQL:
select * from ticket t
join tollBoothShift tbs on t.fkTollBoothShift = tbs.uniqueId
join classification c on c.uniqueId = t.fkClassification
join classificationPrice cp on cp.fkClassification = c.uniqueId
join person p on p.uniqueId = tbs.fkPerson
WHERE convert(date, t.entryDate) = '6/20/2018'
and (convert(time, t.entryDate) >= convert(time, '12:00')
and convert(time, t.entryDate) <= convert(time, '15:00'))
and cp.entryDate = (SELECT MAX(entryDate)
from classificationPrice
where classificationPrice.fkClassification = c.uniqueId
and entryDate <= t.entryDate)
order by convert(time, t.entryDate)
I have attempted to do so here:
from t in context.Ticket
join c in context.Classification on t.FkClassification equals c.UniqueId
join cp in context.ClassificationPrice on c.UniqueId equals cp.FkClassification into cpc
let price = cpc.Where(f => f.FkClassification == c.UniqueId && f.EntryDate <= t.EntryDate).OrderByDescending(p => p.EntryDate).Take(1).FirstOrDefault().Price
join tbs in context.TollBoothShift on t.FkTollBoothShift equals tbs.UniqueId
join p in context.Person on tbs.FkPerson equals p.UniqueId
where t.EntryDate.Date == date.Date && (t.EntryDate.TimeOfDay >= startTime.TimeOfDay && t.EntryDate.TimeOfDay <= endTime.TimeOfDay) && t.Weight != null
orderby t.EntryDate.TimeOfDay
select
new WeighingLogReportModel
{
ticketNumber = t.UniqueId.ToString(),
entryDate = t.EntryDate,
entryTime = t.EntryDate.ToShortTimeString(),
tollBoothNumber = tbs.UniqueId.ToString(),
supervisor = "",
weight = t.Weight,
cost = price.ToString("N2"),
ownerDriver = string.Empty,
tollBoothShift = tbs.StartTime.ToShortTimeString() + " to " + tbs.EndTime.Value.ToShortTimeString() + "h",
licencePlatePrefix = t.LicencePlatePrefix,
licencePlateSuffix = t.LicencePlateSuffix
}
It seems, you missed the last condition in LINQ query
and cp.entryDate = (SELECT MAX(entryDate)
from classificationPrice
where classificationPrice.fkClassification = c.uniqueId
and entryDate <= t.entryDate)
You can covert this condition to LINQ and add it to existing where clause
cp.EntryDate == ClassificationPrice.Where(x=> x.FkClassification == c.UniqueId).Max(y=> y.EntryDate)
So your final where clause will be
where t.EntryDate.Date == date.Date
&& (t.EntryDate.TimeOfDay >= startTime.TimeOfDay
&& t.EntryDate.TimeOfDay <= endTime.TimeOfDay)
&& t.Weight != null
&& cp.EntryDate == ClassificationPrice.Where(x=> x.FkClassification == c.UniqueId).Max(y=> y.EntryDate)
So I have this line:
var transrevmax = db.TRANSACTs
.Where(x => x.SITE == "1" &&
x.DATE_IN >= dateinchoice &&
x.DATE_OUT <= dateoutchoice)
.GroupBy(x => x.TICKET_NO)
.Select(x => x.OrderByDescending(y => y.REV_NO).FirstOrDefault())
.ToList();
and it returns the exact list of transactions I want the join below to go through to obtain values from...
var exportrecovery = (from trans in transrevmax
join detail in db.DETAILs on new { TICKET_NO = trans.TICKET_NO, REV_NO = trans.REV_NO } equals new { TICKET_NO = detail.TICKET_NO, REV_NO = detail.REV_NO }
join job in db.JOBs on new { JOB_CODE = trans.JOB_CODE, CUST_CODE = trans.CUST_CODE } equals new { JOB_CODE = job.CODE, CUST_CODE = job.CUST_CODE }
join customer in db.CUSTOMERs on trans.CUST_CODE equals customer.CODE
join invoiced in db.INVOICEDs on trans.TICKET_NO equals invoiced.TICKET_NO
where trans.DATE_IN >= dateinchoice && trans.DATE_OUT <= dateoutchoice && trans.STATUS.ToString().Trim() != "V" && trans.STATUS.ToString().Trim() != "E"
select new { ADDRESS = customer.ADDRESS, CITY = customer.CITY, STATE = customer.STATE, ZIP = customer.ZIP, FREIGHT = detail.HAUL_CHGE + detail.FUEL_CHGE, JOB_NAME = job.NAME, HAUL_TAX = detail.HAUL_TAX, INVOICE_NO = invoiced.INVOICE_NO, CUST_NAME = customer.NAME, TAX_CODE = customer.TAX_CODE, MAT_CHGE = detail.MAT_CHGE, MAT_TAX = detail.MAT_TAX, MAT_CODE = detail.MAT_CODE, QTY = detail.QTY, PRICE = detail.PRICE, DATE_MOD = trans.DATE_OUT, REV_NO = trans.REV_NO, SITE = trans.SITE, TICKET_NO = trans.TICKET_NO, CUST_CODE = trans.CUST_CODE, JOB_CODE = trans.JOB_CODE }
).ToList();
... if I run the first line I get the transactions limited to only those with the max revision (what I want), and if I run the join (replacing the "transrevmax" with the table "db.TRANSACTs") I get the right range of ticket numbers, but it includes all revisions. I am stumped as to how I can use the joined tables and get only unique rows according to their (maximum) revision number. When these two are used in conjunction I receive zero rows. Please advise.
Remove the ToList on the transrevmax creation.
var Getdetails = (from p in XYZDb.tblPulls
join
ro in XYZDb.tblRentalOrders
on p.AffCode equals ro.AffCode.Value
join
tpsb in XYZDb.tblPullSheetBatchProcessings
on p.PullNo.ToString() equals tpsb.PullSheet
select new
{
PullNos = p.PullNo,
AffCode = p.AffCode,
TotalItems = p.TotalItems,
p.PostedOn,
p.UpdatedOn,
p.IsPrinted,
BatchName = tpsb.BatchName
})
.Where(i => i.PostedOn >= from_date && i.PostedOn <= to && i.IsPrinted != null).Distinct();
In the above code only the pullno having BatchName are coming, i want to retrieve all the pullno within that timezone, and if it is batched, then the BatchName will also appear. I am stuck on that. Any kind of help will be appreciated. Feel free to ask any question.
Use left outer join,
var Getdetails = (from p in XYZDb.tblPulls
join
ro in XYZDb.tblRentalOrders
on p.AffCode equals ro.AffCode.Value
join
tpsb in XYZDb.tblPullSheetBatchProcessings
on p.PullNo.ToString() equals tpsb.PullSheet into pt
from batch in pt.DefaultIfEmpty()
select new
{
PullNos = p.PullNo,
AffCode = p.AffCode,
TotalItems = p.TotalItems,
p.PostedOn,
p.UpdatedOn,
p.IsPrinted,
BatchName = (batch == null ? String.Empty : batch.BatchName )
})
.Where(i => i.PostedOn >= from_date && i.PostedOn <= to && i.IsPrinted != null).Distinct();
below I have listed a linq query that works properly in my asp.net.mvc web app.
In addition I would like to group over 'allowance.ParameterId' in order to get the group sum for 'allowance.Freight (instead of multiple records for the given key).
var query = from ara in aras
join company in companies on ara.Id equals company.ARAId
join wasteWater in wasteWaters on company.Id equals wasteWater.CompanyId
join allowance in allowances on wasteWater.Id equals allowance.WasteWaterID
join parameter in parameters on allowance.ParameterId equals parameter.Id into JoinedParameterAllowance
from parameter in JoinedParameterAllowance.DefaultIfEmpty()
where company.Activ == true && company.End == null && company.Template == false
&& wasteWater.End == null
select new FreightSummaryViewModel
{
AraName = ara.Name,
AraId = ara.Id,
AllowedParameter = parameter.Name,
AllowedFreight = allowance.Freight
};
I have tried to insert 'group ...' but failed to get it right.
Could someone help me please to set up the proper syntax?
Thank you in advance, Manu
I have little idea about relations in your database, so I improvised...
// Some dummy data to play with
var aras = Enumerable.Range(0, 5).Select(i => new { Id = i, Name = "Ara" + i });
var companies = Enumerable.Range(0, 15).Select(i => new { Id = i, ARAId = i % 5, Activ = true, End = (DateTime?)null, Template = false });
var wasteWaters = Enumerable.Range(0, 35).Select(i => new { Id = i, CompanyId = i / 15, End = (DateTime?)null });
var allowances = Enumerable.Range(0, 70).Select(i => new { Id = i, WasteWaterID = i, ParameterId = i % 4, Freight = i * 1000 });
var parameters = Enumerable.Range(0, 4).Select(i => new { Id = i, Name = "Parameter" + i });
And this is what I believe you looked for:
var query =
from ara in aras
join company in companies on ara.Id equals company.ARAId
join wasteWater in wasteWaters on company.Id equals wasteWater.CompanyId
join allowance in allowances on wasteWater.Id equals allowance.WasteWaterID
join parameter in parameters on allowance.ParameterId equals parameter.Id
into JoinedParameterAllowance
// from parameter in JoinedParameterAllowance.DefaultIfEmpty()
where true
&& company.Activ == true
&& company.End == null
&& company.Template == false
&& wasteWater.End == null
group allowance by new
{
AraName = ara.Name,
AraId = ara.Id,
ParameterId = allowance.ParameterId
} into myGroup
select new //FreightSummaryViewModel
{
AraName = myGroup.Key.AraName,
AraId = myGroup.Key.AraId,
AllowedParameter = myGroup.Key.ParameterId,
AllowedFreight = myGroup.Sum(g => g.Freight)
};
I have difficulty in getting an average score of students in each department.
while every department there are many faculties, each faculty there are many courses, each course there are many students, and every student has a lot of value.
the query that I have made, I get quite a lot of the time constraints that are required to display the same data capture.
please help to optimize the query that I made this.
double TotalNilaiMutu = 0;
double JumSKS = 0;
double ipkMhs = 0;
double totalIPK = 0;
var queryDepartemen = (from so in StrukturOrganisasis
join dp in Departemens on so.ID equals dp.ID
orderby dp.ID
select new{dp.ID, so.Inisial, so.Nama}).ToList();
foreach(var departemen in queryDepartemen){
var queryMayor = (from my in Mayors
where my.DepartemenID == departemen.ID && my.StrataID == 2
select my.ID).ToList();
var queryMhs = (from ms in MahasiswaSarjanas
where queryMayor.Contains(ms.MayorID) &&
(
from sm in StatusMahasiswas
where
(
from ts in TahunSemesters
where ts.TahunAwal == 2013
select ts.ID
)
.Contains(sm.TahunSemesterID)
select sm.NIM
)
.Contains(ms.NIM)
select ms.NIM).ToList();
ipkMhs = 0;
foreach(var nim in queryMhs){
var queryNilai = (from kr in KRS
join hm in HurufMutus on kr.HurufMutuID equals hm.ID
join kur in
(
from ku in Kurikulums
join mk in MataKuliahs on ku.MataKuliahID equals mk.ID
select new {ku.ID, mk.Nama, mk.SKS}
)
on kr.KurikulumID equals kur.ID
where kr.NIM==nim
select new {
nilai = hm.NilaiMutu * kur.SKS,
sks = kur.SKS
});
TotalNilaiMutu = 0;
JumSKS = 0;
foreach(var ipk in queryNilai){
TotalNilaiMutu += ipk.nilai;
JumSKS += ipk.sks;
}
if(double.IsNaN(TotalNilaiMutu/JumSKS)) ipkMhs+=0;
else ipkMhs += TotalNilaiMutu/JumSKS;
}
if(double.IsNaN(ipkMhs/queryMhs.Count())) totalIPK=0;
else totalIPK=ipkMhs/queryMhs.Count();
Console.WriteLine(departemen.Nama +" -> "+ totalIPK +" : "+ ipkMhs +" / "+queryMhs.Count());
}
Have you tried adding AsParallel()?
var queryDepartemen = (from so in StrukturOrganisasis.AsParallel()
join dp in Departemens on so.ID equals dp.ID
orderby dp.ID
select new{dp.ID, so.Inisial, so.Nama}).ToList();
foreach(var departemen in queryDepartemen.AsParallel()){
var queryMayor = (from my in Mayors
where my.DepartemenID == departemen.ID && my.StrataID == 2
select my.ID).ToList();
var queryMhs = (from ms in MahasiswaSarjanas.AsParallel()
where queryMayor.Contains(ms.MayorID) &&
(
from sm in StatusMahasiswas
where
(
from ts in TahunSemesters
where ts.TahunAwal == 2013
select ts.ID
)
.Contains(sm.TahunSemesterID)
select sm.NIM
)
.Contains(ms.NIM)
select ms.NIM).ToList();