C# subquery in LINQ select - c#

I'm trying to convert this query to LINQ, but I'm not getting the value of the subquery
QUERY:
select c.cod, c.cpfcnpj, c.razaosocial, c.nome, c.fone, c.celular, c.email, c.dtcad, s.dataval as validade,
(select max(datapagamento) from vendas where c.cod = coduser) as datapag
from usuarios c, libsys s
WHERE c.cod = s.codcli
and c.cod in (select coduser from vendas)
AND c.cod in (select l.codcli from libsys l where l.dataval >= current_date)
order by c.dtcad asc
LINQ:
var rel = await (from u in _contexto.usuarios
from v in _contexto.libsys
where (
(u.cod == v.codcli) &&
_contexto.vendas.Any(y => y.coduser == u.cod) &&
_contexto.libsys.Any(y => y.codcli == u.cod && y.pcpdataval >= System.DateTime.Now)
)
select new RelatorioLicsModel
{
cod = u.cod,
cpfcnpj = u.cpfcnpj,
razaosocial = u.razaosocial,
nome = u.nome,
fone = u.fone,
celular = u.celular,
email = u.email,
dtcad = u.dtcad,
validade = v.pcpdataval.ToString(),
dtpag = Convert.ToDateTime(_contexto.vendas.Where(s => s.datapagamento == _contexto.vendas.Max(x => x.datapagamento) && s.coduser == u.cod).FirstOrDefault())
}).ToListAsync();
the error I get is:
{"You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(PARTITION BY v.coduser ORDER BY v.cod) AS row\r\n FROM vendas ' at line 7"}
is this the correct way to do this? thanks for any help!

Problem with dtpag property.
var query =
from u in _contexto.usuarios
from v in _contexto.libsys
where (
(u.cod == v.codcli) &&
_contexto.vendas.Any(y => y.coduser == u.cod) &&
_contexto.libsys.Any(y => y.codcli == u.cod && y.pcpdataval >= System.DateTime.Now)
)
select new RelatorioLicsModel
{
cod = u.cod,
cpfcnpj = u.cpfcnpj,
razaosocial = u.razaosocial,
nome = u.nome,
fone = u.fone,
celular = u.celular,
email = u.email,
dtcad = u.dtcad,
validade = v.pcpdataval.ToString(),
dtpag = Convert.ToDateTime(_contexto.vendas.Where(s => s.coduser == u.cod).Max(x => x.datapagamento))
}

Related

Convert SQL to Lambda Linq Expression with Inner Join on multiple condition

How do I convert this SQL to Lambda expression:
SELECT L.LotNo,
L.ProcessCode,
L.ProcessName,
L.MachineNo,
M.MaterialLotNo,
M.MaterialName,
M.StartTime,
M.EndTime
FROM LotProgress L
INNER JOIN MaterialMount M
ON (M.MachineNo = L.MachineNo OR M.MachineNo =
(SELECT ParentMachineNo FROM Machine WHERE MachineNo = L.MachineNo))
AND (L.StartTime <= M.EndTime OR M.EndTime IS NULL)
AND (L.EndTime >= M.StartTime OR L.EndTime IS NULL)
I am struggluing to convert the multiple condition on Inner Join.
This is as far as I can go:
var vewMaterialTrace = viewLotProgress
.Join(viewMaterialMount, a => a.MachineNo, b => b.MachineNo,
(a, b) => new viewMaterial
{
LotNo = a.LotNo,
ProcessCode = a.ProcessCode,
ProcessName = a.ProcessName,
MachineNo = a.MachineNo,
OpeGroupCode = b.OpeGroupCode,
OpeGroupName = b.OpeGroupName,
MaterialLotNo = b.MaterialLotNo,
MaterialName = b.MaterialName,
StartTime = b.StartTime,
EndTime = b.EndTime,
}).ToList();
I'm not sure my code is correct or not but is too long to add in comment. Please try
var result = context.LotProgress
.Join(context.MaterialMount,
l => l.MachineNo,
m => m.MachineNo,
(l, m) => new { l, m })
.Where(x => x.l.MachineNo == x.m.MachineNo || x.m.MachineNo == context.Machine.FirstOrDefault(y => y.MachineNo == x.l.MachineNo).ParentMachineNo)
.Where(x => x.l.StartTime <= x.m.EndTime || x.m.EndTime == null)
.Where(x => x.l.EndTime >= x.m.StartTime || x.l.EndTime == null)
.Select(x => new
{
LotNo = x.l.LotNo,
ProcessCode = x.l.ProcessCode,
ProcessName = x.l.ProcessName,
MachineNo = x.l.MachineNo,
MaterialLotNo = x.m.MaterialLotNo,
MaterialName = x.m.MaterialName,
StartTime = x.m.StartTime,
EndTime = x.m.EndTime
});

Why Same where clause need to write multiple times in a Linq Query for following SQL

What will be the proper linq syntax of below SQL Query ?
select a.id, a.AppointmentStatusID, ad.ID as DetailID
from [dbo].[Appointment] a, [dbo].[AppointmentDetail] ad
where a.[ID] = ad.[AppointmentID]
and a.CompanyID = 'a3dea87a-804e-4115-98cf-472988cf1678'
and a.LocationID = '3165caca-2a48-46f0-bbed-578cff29167t'
and ad.AppDateFrom <= {ts '2017-11-14 23:59:31'}
and ad.AppDateTo >= {ts '2017-11-14 00:00:00'}
and ad.[ApprovalStatusID] = 2
Problem I faced:
I required to filter Where Condition two times 1st at the time within the join & 2nd time during the object.Select expression, please check bellow
var results = (from a in appointments
join ad in _appointmentDetailRepository.GetAll() on a.ID equals ad.AppointmentID
where ad.ApprovalStatusID == 2
&& DbFunctions.TruncateTime(ad.AppDateFrom) <= DbFunctions.TruncateTime(viewmodel.AppointmentDate)
&& DbFunctions.TruncateTime(ad.AppDateTo) >= DbFunctions.TruncateTime(viewmodel.AppointmentDate)
orderby a.ID
select new Appointment
{
ID = a.ID,
CompanyID = a.CompanyID,
LocationID = a.LocationID,
AppointmentDetail = a.AppointmentDetail.Select(ad => new AppointmentDetail
{
ID = ad.ID,
AppDateFrom = ad.AppDateFrom,
AppDateTo = ad.AppDateTo,
AppointmentStatusID = ad.AppointmentStatusID,
}).Where(ad=> ad.ApprovalStatusID == 2
&& DbFunctions.TruncateTime(ad.AppDateFrom) <= DbFunctions.TruncateTime(viewmodel.AppointmentDate)
&& DbFunctions.TruncateTime(ad.AppDateTo) >= DbFunctions.TruncateTime(viewmodel.AppointmentDate)).ToList()
}).GroupBy(x => x.ID).Select(x => x.DefaultIfEmpty().FirstOrDefault());
Query : Why I required to write Where clause 2 times ?
Required Result
An Appointment Object --> Containing ICollection<AppoinmentDetails> if Details.Where Condition == True
From what I see (without knowing the model you have), it looks like you should use the already joined and filtered Details from ad instead of looking it up again from the Property a.AppointmentDetail...
Untested:
select new Appointment
{
ID = a.ID,
CompanyID = a.CompanyID,
LocationID = a.LocationID,
AppointmentDetail = ad.ToList(), // <-- don't you think?
...
}
For the given SQL query
select a.id, a.AppointmentStatusID, ad.ID as DetailID
from [dbo].[Appointment] a, [dbo].[AppointmentDetail] ad
where a.[ID] = ad.[AppointmentID]
and a.CompanyID = 'a3dea87a-804e-4115-98cf-472988cf1678'
and a.LocationID = '3165caca-2a48-46f0-bbed-578cff29167t'
and ad.AppDateFrom <= {ts '2017-11-14 23:59:31'}
and ad.AppDateTo >= {ts '2017-11-14 00:00:00'}
and ad.[ApprovalStatusID] = 2
LINQ query can be written as
var results = (from a in appointments
join ad in appointmentDetails on a.ID equals ad.AppointmentID
where ad.ApprovalStatusID == 2
&& a.CompanyID == "a3dea87a-804e-4115-98cf-472988cf1678"
&& a.LocationID == "3165caca-2a48-46f0-bbed-578cff29167t"
&& ad.AppDateFrom.Date <= viewmodel.AppointmentDate.Date
&& ad.AppDateTo.Date >= viewmodel.AppointmentDate.Date
select new
{
ID = a.ID,
AppointmentStatusID = a.AppointmentStatusID,
DetailID = ad.ID
}).ToList();
You can also write it like
var results = appointmentDetails
.Where(ad => ad.AppDateFrom.Date <= viewmodel.AppointmentDate.Date
&& ad.AppDateTo.Date >= viewmodel.AppointmentDate.Date
&& ad.ApprovalStatusID == 2
&& ad.Appointment.CompanyID == "a3dea87a-804e-4115-98cf-472988cf1678"
&& ad.Appointment.LocationID == "3165caca-2a48-46f0-bbed-578cff29167t")
.Select(ad =>
new
{
ID = ad.Appointment.ID,
AppointmentStatusID = ad.Appointment.AppointmentStatusID,
DetailID = ad.ID
})
.ToList()
As per the updated question, to get the the Appointment object with a collection of AppointmentDetails, please try this query
var results = appointmentDetails
.Where(ad => ad.AppDateFrom.Date <= viewmodel.AppointmentDate.Date
&& ad.AppDateTo.Date >= viewmodel.AppointmentDate.Date
&& ad.ApprovalStatusID == 2
&& ad.Appointment.CompanyID == "a3dea87a-804e-4115-98cf-472988cf1678"
&& ad.Appointment.LocationID == "3165caca-2a48-46f0-bbed-578cff29167t")
.Select(ad =>
new
{
ID = ad.Appointment.ID,
AppointmentStatusID = ad.Appointment.AppointmentStatusID,
Detail = ad
})
.AsEnumerable()
.GroupBy(a => new { a.ID, a.AppointmentStatusID })
.Select(a => new Appointment
{
ID = a.Key.ID,
AppointmentStatusID = a.Key.AppointmentStatusID,
AppointmentDetails = a.Select(d => d.Detail).ToList()
})
.ToList();

Yet another “A query body must end with a select clause or a group clause”

This query does work, but I am trying to combine the two steps into one query.
var query1 = from b in db.GetTable<Boats>()
from o in db.GetTable<Offices>()
from u in db.GetTable<Users>()
.Where
(u =>
u.UserId == b.Handling_broker &&
o.Office == b.Handling_office &&
b.Status == 2 &&
officesToInclude.Contains(b.Handling_office)
)
select new
{
hOffice = o.Name,
bName = u.Name
};
var query2 = query1.GroupBy(t => new { office = t.hOffice, name = t.bName })
.Select(g => new { Office = g.Key.office, Name = g.Key.name, Count = g.Count() });
If I try to combine the two queries using the following query it gives me the “A query body must end with a select clause or a group clause” error.
var query1 = from b in db.GetTable<Boats>()
from o in db.GetTable<Offices>()
from u in db.GetTable<Users>()
.Where
(u =>
u.UserId == b.Handling_broker &&
o.Office == b.Handling_office &&
b.Status == 2 &&
officesToInclude.Contains(b.Handling_office)
)
.GroupBy(t => new { office = t.Office, name = t.Name })
.Select(g => new { Office = g.Key.office, Name = g.Key.name, Count = g.Count() });
I think I have to add a select something, but I can't figure out what.
Can anyone please help?
Your query must contain a select clause. The .Where(...).GroupBy(...).Select(...) are only on the db.GetTable<Users>(). Something like:
var query1 = from b in db.GetTable<Boats>()
from o in db.GetTable<Offices>()
from u in db.GetTable<Users>().Where(u => u.UserId == b.Handling_broker &&
o.Office == b.Handling_office &&
b.Status == 2 &&
officesToInclude.Contains(b.Handling_office))
.GroupBy(t => new { office = t.Office, name = t.Name })
.Select(g => new { Office = g.Key.office, Name = g.Key.name, Count = g.Count() })
select new { /* Desired properties */};
But I think you are looking for something like:
var result = from b in db.GetTable<Boats>()
from o in db.GetTable<Offices>()
from u in db.GetTable<Users>()
where u.UserId == b.Handling_broker &&
o.Office == b.Handling_office &&
b.Status == 2 &&
officesToInclude.Contains(b.Handling_office))
group 1 by new { t.Office, t.Name } into g
select new { Office = g.Key.Office, Name = g.Key.Name, Count = g.Count() };

LINQ pivot top 5 rows to columns

The desired output is a set of rows containing details about a physician and the top 5 procedures they performed (by volume) that are not in our benchmarking tables - with a minimum of one per month. Even with my limited LINQ experience, I have managed to get this working, but the performance in abysmal. In the spirit of becoming better at LINQ, I thought I'd see if there was a better way to approach this (besides coding in SQL).
Here is the entire method, although I believe it is the final statement (var report =) that deserves the most attention.
//Get the Providers for the selected AccessLevel & Report Period
var providerRiskLevels = GetProviderRiskLevelForAccessLevel(userAccessLevelId, reportPeriodId, providerNamePiece);
short benchmarkYear = (
from rp in db.ReportPeriods
where rp.ReportPeriodId == reportPeriodId
select rp.BenchmarkDataYear
).FirstOrDefault();
byte Duration = (
from rp in db.ReportPeriods
where rp.ReportPeriodId == reportPeriodId
select rp.Duration
).FirstOrDefault();
//Summarize counts by procedure code (ignoring modifiers)
var codeCounts =
from pp in db.ProviderProductions
//332 - restrict to valid codes
join pc in db.ProcedureCodes on pp.ProcedureCode equals pc.ProcedureCode1
where pp.ReportPeriodId == reportPeriodId
//show deleted codes as potential issue
&& pc.TerminatedDate == null
&& (codeFilter == null || pp.ProcedureCode == codeFilter)
join pc in db.PspsProcedures
on new { col1 = pp.ProcedureCode, col2 = benchmarkYear } equals new { col1 = pc.ProcedureCode, col2 = pc.Year } into left
from l_d in left.DefaultIfEmpty()
where l_d == null
group pp by
new { pp.ProviderId, pp.ProcedureCode }
into g
orderby g.Key.ProviderId, g.Sum(x => x.Volume) descending
where g.Sum(x => x.Volume) > Duration
select new NewCodesEntity
{
ProviderId = g.Key.ProviderId,
ProcedureCode = g.Key.ProcedureCode,
Volume = g.Sum(x => x.Volume)
};
//Get top 5 procedures performed by provider
var newCodes =
from cc in codeCounts
group cc by
new { cc.ProviderId }
into g
select new ProviderNewCodesEntity
{
ProviderId = g.Key.ProviderId,
Codes = g.OrderByDescending(x => x.Volume).Take(5).ToList()
};
//Build the report
var report =
from pr in providerRiskLevels
join nc in newCodes on pr.Provider.ProviderId equals nc.ProviderId
where pr.RiskCategoryId == RiskCategoryIds.VisibleRisk
&& (filterRiskLevelNums.Contains(pr.RiskLevelNum))
&& (filterSpecialtyId == 0 || pr.Provider.Specialty.SpecialtyId == filterSpecialtyId)
select new ProbeAuditEntity
{
ProviderId = pr.Provider.ProviderId,
ProviderName = pr.Provider.Name,
ProviderCode = pr.Provider.ProviderCode,
SpecialtyName = pr.Provider.Specialty.Name,
SpecialtyCode = pr.Provider.Specialty.SpecialtyCode,
VisibleRisk = pr.RiskScore,
NewCode1 = nc.Codes.OrderByDescending(c => c.Volume).FirstOrDefault().ProcedureCode,
NewCode2 = nc.Codes.OrderByDescending(c => c.Volume).Skip(1).FirstOrDefault().ProcedureCode,
NewCode3 = nc.Codes.OrderByDescending(c => c.Volume).Skip(2).FirstOrDefault().ProcedureCode,
NewCode4 = nc.Codes.OrderByDescending(c => c.Volume).Skip(3).FirstOrDefault().ProcedureCode,
NewCode5 = nc.Codes.OrderByDescending(c => c.Volume).Skip(4).FirstOrDefault().ProcedureCode
};
return report;
I appreciate your suggestions.
Give this a try for the report:
//Build the report
var report =
(from pr in providerRiskLevels
join nc in newCodes on pr.Provider.ProviderId equals nc.ProviderId
where pr.RiskCategoryId == RiskCategoryIds.VisibleRisk
&& filterRiskLevelNums.Contains(pr.RiskLevelNum)
&& (filterSpecialtyId == 0
|| pr.Provider.Specialty.SpecialtyId == filterSpecialtyId)
select new
{
RiskLevel = pr,
NewCodes = nc.Codes.OrderByDescending(c => c.Volumn).Select(c => c.ProcedureCode).Take(5)
})
.AsEnumerable()
.Select(x => new ProbeAuditEntity
{
ProviderId = x.RiskLevel.Provider.ProviderId,
ProviderName = x.RiskLevel.Provider.Name,
ProviderCode = x.RiskLevel.Provider.ProviderCode,
SpecialtyName = x.RiskLevel.Provider.Specialty.Name,
SpecialtyCode = x.RiskLevel.Provider.Specialty.SpecialtyCode,
VisibleRisk = x.RiskLevel.RiskScore,
NewCodes = x.NewCodes.Concat(Enumerable.Repeat(<DefaultProcedureCodeHere>, 5)).Take(5)
});
Or, if ProbeAuditEntity is a class you could do this:
//Build the report
var report =
(from pr in providerRiskLevels
join nc in newCodes on pr.Provider.ProviderId equals nc.ProviderId
where pr.RiskCategoryId == RiskCategoryIds.VisibleRisk
&& filterRiskLevelNums.Contains(pr.RiskLevelNum)
&& (filterSpecialtyId == 0
|| pr.Provider.Specialty.SpecialtyId == filterSpecialtyId)
select new ProbeAuditEntity
{
ProviderId = x.RiskLevel.Provider.ProviderId,
ProviderName = x.RiskLevel.Provider.Name,
ProviderCode = x.RiskLevel.Provider.ProviderCode,
SpecialtyName = x.RiskLevel.Provider.Specialty.Name,
SpecialtyCode = x.RiskLevel.Provider.Specialty.SpecialtyCode,
VisibleRisk = x.RiskLevel.RiskScore,
NewCodes = nc.Codes.OrderByDescending(c => c.Volumn).Select(c => c.ProcedureCode).Take(5)
})
.ToList();
report
.ForEach(x => x.NewCodes = x.NewCodes.Concat(Enumerable.Repeat(<DefaultProcedureCodeHere>, 5)).Take(5);

LInq to Entity select new COUNT where

I've created the most complex linq query ever, but still do not have exactly what I need. From this query, I need to know how many related students in the EventStudents table that have a DateDeleted == null. So, the StudentCount = ev.EventStudents - where DateDeleted == null .Count().
Can anyone help with this please?
var inf = (from ev in db.Events
where (ev.StartDate >= beginDate && ev.StartDate <= endDate)
&& ev.DeletedDate == null
orderby ev.StartDate descending
select new
{
EventID = ev.EventID,
EventTitle = ev.Title,
EventDate = ev.StartDate,
StudentCount = ev.EventStudents.Count(),
CreatedUsername = ev.CreatedUsername
}).AsEnumerable().Select(x => new
{
EventID = x.EventID,
EventTitle = x.EventTitle,
EventDate = x.EventDate,
StudentCount = x.StudentCount,
CreatedUsername = x.CreatedUsername,
CreatedFullname = sortedUserDictionary.Where(u => u.Value == x.CreatedUsername)
.Select(f => f.Key)
.FirstOrDefault() ?? x.CreatedUsername
});
Change ev.EventStudents.Count() to ev.EventStudents.Count(es => es.DateDeleted == null).

Categories