Conditional retrieval of data through linq in C# - c#

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();

Related

Linq query: inner join with a count() group by subquery

We have some Machines having Devices attached. Not all the machines have devices atached and the devices cand be moved between machines. The devices generate Errors and we need to count those errors occured in the past day.
We have four tables: Machines (with Id and Code), Devices (with Id and Code), a pairing table DevicesMachines (Id, IdMachine, IdDevice, From datetime, To datetime) and Errors(Id, IdDevice, Moment datetime, Description).
The working SQL query is this:
Select m.Id, m.Code,
Coalesce(d.Code, 'NA') As DeviceCode,
Coalesce(Err.ErrorCnt,0) As ErrorCnt
From Machines As m
Left Outer Join (Select IdMachine, IdDevice From DevicesMachines as dm
Where GetDate() Between dm.From And dm.To) As dm on m.Id=dm.IdMachine
Left Outer Join Devices As d on dm.IdDevice=d.Id
Left outer join
( Select IdMachine, Count(Id) As ErrorCnt From Errors as er
Where er.Moment >= DateAdd(day,-1,GetUtcDate())
Group By IdMachine) As Err
On m.Id=Err.IdMachine
I have tried many syntaxes, one of which is below:
using ( DataContextM dcMachines = new dataContextM())
{
IEnumerable<MachineRow> lstM =
from m in dcMachines.Machines
from dm in dcMachines.DevicesMachines.Where(dm => (dm.IdMachine == m.Id) && (dm.From <= DateTime.Now) && (dm.To >= DateTime.Now)).DefaultIfEmpty()
from d in dcMachines.Devices.Where(d => d.Id == dm.IdDevice).DefaultIfEmpty()
from er in dcMachines.Errors
.Where(er => (er.Moment >= DateTime.Now) && (er.Moment <= DateTime.Now.AddDays(-1)))
.GroupBy(er => er.IdMachine)
.Select(er => new { IdMachine = er.Key, ErrorCnt = er.Count() })
.Where(er=> er.IdMachine==m.Id).DefaultIfEmpty()
select new MachineRow
{
Id = amId,
Code = m.Code,
DeviceCode = (d == null) ? "NA" : d.DeviceCode,
IdDevice = (d == null) ? 0: d.Id,
ErrorCnt = (er == null) ? 0 : er.ErrorCnt
};
}
I failed to find the right Linq syntax and I need your help.
Thank you,
Daniel
Based on the SQL you provided, I created what I think is the equivalent EF LINQ expression:
using (var dcMachines = new DataContextM())
{
var now = DateTime.Now;
var utcYesterday = DateTime.UtcNow.AddDays(-1);
var devicesMachinesQuery =
from dm in dcMachines.DevicesMachines
where dm.From <= now && dm.To >= now
join d in dcMachines.Devices on dm.IdDevice equals d.Id into dItems
from d in dItems.DefaultIfEmpty()
select new
{
dm.IdMachine,
dm.IdDevice,
DeviceCode = d != null ? d.Code : "NA"
};
var errorsQuery =
from err in dcMachines.Errors
where err.Moment >= utcYesterday
select err;
IEnumerable<MachineRow> lstM =
from m in dcMachines.Machines
join dm in devicesMachinesQuery on m.Id equals dm.IdMachine into dmItems
from dm in dmItems.DefaultIfEmpty()
select new MachineRow
{
Id = m.Id,
Code = m.Code,
DeviceCode = dm != null ? dm.DeviceCode : "NA",
IdDevice = dm != null ? dm.IdDevice : 0,
ErrorCnt = (
from err in errorsQuery
where err.IdMachine == m.Id
select err.Id
)
.Count()
};
}
I made some tests in memory and it seems to yield the same behavior as your provided SQL query.

Converting SQL to LINQ C# to return data with most recent entry of a field

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)

How to Use Data Inside Var in Linq?

I want to sum records using Group by from the all data inside "result view".
can anyone guide me for this.!
Here is My Code
var tData1 = (from i in _data.Transactions
join y in _data.DeviceInformations on i.DeviceInfoId equals y.DeviceInfoId
join u in _data.AccountDevices on y.DeviceInfoId equals u.DeviceInfoId
where y.Active == true && u.AccountId == 1000001 && u.Active == true
group i by i.DeviceInfoId into g
select g.OrderByDescending(t => t.DateCreated)).ToList();
foreach (var xCo in tData1)
{
//I am getting Data in xCo
}
Based on #Nayeem Mansoori solution you can try this.
var tData1 = (from i in _data.Transactions
join y in _data.DeviceInformations on i.DeviceInfoId equals y.DeviceInfoId
join u in _data.AccountDevices on y.DeviceInfoId equals u.DeviceInfoId
where y.Active == true && u.AccountId == 1000001 && u.Active == true
group i by i.DeviceInfoId into g
select new {Id = DeviceInfoId, sum = g.Sum(x=>x.DeviceInfoId)};

How can i use a where clause within a select statement in linq. (ie. on a property.)

I have this linq query:
var sku = (from a in con.MagentoStockBalances
join b in con.MFGParts on a.SKU equals b.mfgPartKey
join c in con.DCInventory_Currents on b.mfgPartKey equals c.mfgPartKey
where a.SKU != 0 && c.dcKey ==6
select new
{
Part_Number = b.mfgPartNumber,
Stock = a.stockBalance,
Recomended = a.RecomendedStock,
Cato = c.totalOnHandQuantity
}).ToList();
Now i need to remove the c.dcKey ==6 condition and have something like this:
var sku = (from a in con.MagentoStockBalances
join b in con.MFGParts on a.SKU equals b.mfgPartKey
join c in con.DCInventory_Currents on b.mfgPartKey equals c.mfgPartKey
where a.SKU != 0
select new
{
Part_Number = b.mfgPartNumber,
Stock = a.stockBalance,
Recomended = a.RecomendedStock,
Cato = c.totalOnHandQuantity where c.dcKey == 6,
Kerry = c.totalOnHandQuantity where c.dcKey == 7
}).ToList();
Something like this:
Cato = c.dcKey == 6 ? c.totalOnHandQuantity : 0,
Kerry = c.dcKey == 7 ? c.totalOnHandQuantity : 0
The ?: syntax is called a conditional operator.
Instead of adding another join, I would use a separate query in a let:
from a in con.MagentoStockBalances
join b in con.MFGParts on a.SKU equals b.mfgPartKey
where a.SKU != 0
let cs = con.DCInventory_Currents.Where(c => b.mfgPartKey == c.mfgPartKey)
select new
{
Part_Number = b.mfgPartNumber,
Stock = a.stockBalance,
Recomended = a.RecomendedStock,
Cato = cs.Single(c => c.dcKey == 6).totalOnHandQuantity
Kerry = cs.Single(c => c.dcKey == 7).totalOnHandQuantity
}
Though I have no idea how well will LINQ to SQL handle a query like this (if it handles it at all).
var query= from x in context.a
where String.IsNullOrEmpty(param1) || (x.p == param1 && x.i == param2)
select x;

why does LINQ To SQL result in SQL like this?

When LINQ translates the below syntax to SQL, the (inner) where clause gets moved to the outer-most query. That's super-unfriendly to the database. I wrote this like Hibernate's HQL (is this appropriate?), and I've written SQL for many moons.
Can anyone help explain what gives, or point me in the way of a resolution?
var rc = (
from dv in (
from dv_j in (
from x in adc.JobManagement
join j in adc.Job on x.JobId equals j.JobId
join js in adc.JobStatus on j.StatusId equals js.JobStatusId
join cm in adc.ClientManagement on j.ClientId equals cm.ClientId
join o in adc.User on cm.UserId equals o.UserId
join jm in adc.JobManagement on j.JobId equals jm.JobId
where
(x.UserId == aid || cm.UserId == aid)
&& (j.StatusDate == null || j.StatusDate >= getFromDate())
&& (jm.ManagementRoleCode == MR_MANAGER)
select new
{
j.JobId,
Job = j.InternalName == null ? j.ExternalName : j.InternalName,
JobStatusDate = j.StatusDate,
JobStatus = js.Code,
Owner = o.Username,
Role = jm.ManagementRoleCode
})
join s in adc.Submission on dv_j.JobId equals s.JobId into dv_s
from s in dv_s.DefaultIfEmpty()
select new
{
dv_j.JobId,
dv_j.Job,
dv_j.JobStatusDate,
dv_j.JobStatus,
dv_j.Owner,
dv_j.Role,
s.SubmissionId,
s.CandidateId,
s.SubmissionDate,
StatusDate = s.StatusDate,
StatusId = s.StatusId
})
join c in adc.Candidate on dv.CandidateId equals c.CandidateId into dv_c
join ss in adc.SubmissionStatus on dv.StatusId equals ss.SubmissionStatusId into dv_ss
from c in dv_c.DefaultIfEmpty()
from ss in dv_ss.DefaultIfEmpty()
orderby
dv.StatusId == null ? dv.StatusDate : dv.JobStatusDate descending,
dv.Job,
c.LastName,
c.NickName,
c.FirstName
select new Projects
{
Id = dv.JobId,
Project = dv.Job,
Submitted = dv.SubmissionDate,
Candidate = FormatIndividual(c.LastName, c.FirstName, c.NickName),
Status = dv.StatusId == null ? ss.Code : dv.JobStatus,
StatusDate = dv.StatusId == null ? dv.StatusDate : dv.JobStatusDate,
Role = dv.Role,
Owner = dv.Owner
});
Try breaking down the one statement into two. This would work as it cannot move the where to a place that doesn't exist yet. This does make multiple round trips to the database, but it is better than having most of several large tables being joined then culled. I would try this:
var inMemoryTable = (
from x in adc.JobManagement
join j in adc.Job on x.JobId equals j.JobId
join js in adc.JobStatus on j.StatusId equals js.JobStatusId
join cm in adc.ClientManagement on j.ClientId equals cm.ClientId
join o in adc.User on cm.UserId equals o.UserId
join jm in adc.JobManagement on j.JobId equals jm.JobId
where
(x.UserId == aid || cm.UserId == aid)
&& (j.StatusDate == null || j.StatusDate >= getFromDate())
&& (jm.ManagementRoleCode == MR_MANAGER)
select new
{
j.JobId,
Job = j.InternalName == null ? j.ExternalName : j.InternalName,
JobStatusDate = j.StatusDate,
JobStatus = js.Code,
Owner = o.Username,
Role = jm.ManagementRoleCode
});
var rc = (
from dv in (
from dv_j in inMemoryTable
join s in adc.Submission on dv_j.JobId equals s.JobId into dv_s
from s in dv_s.DefaultIfEmpty()
select new
{
dv_j.JobId,
dv_j.Job,
dv_j.JobStatusDate,
dv_j.JobStatus,
dv_j.Owner,
dv_j.Role,
s.SubmissionId,
s.CandidateId,
s.SubmissionDate,
StatusDate = s.StatusDate,
StatusId = s.StatusId
})
join c in adc.Candidate on dv.CandidateId equals c.CandidateId into dv_c
join ss in adc.SubmissionStatus on dv.StatusId equals ss.SubmissionStatusId into dv_ss
from c in dv_c.DefaultIfEmpty()
from ss in dv_ss.DefaultIfEmpty()
orderby
dv.StatusId == null ? dv.StatusDate : dv.JobStatusDate descending,
dv.Job,
c.LastName,
c.NickName,
c.FirstName
select new Projects
{
Id = dv.JobId,
Project = dv.Job,
Submitted = dv.SubmissionDate,
Candidate = FormatIndividual(c.LastName, c.FirstName, c.NickName),
Status = dv.StatusId == null ? ss.Code : dv.JobStatus,
StatusDate = dv.StatusId == null ? dv.StatusDate : dv.JobStatusDate,
Role = dv.Role,
Owner = dv.Owner
});

Categories

Resources