Error in SQL query - c#

I'm trying to create a report that displays some information in a DataGrid but I am having a problem with the SQL method. The fields I am displaying are coming from all different tables. When I run the query in MySqlWorkbench it works but when I try run the program in visual studio I get an error.
private static string SearchSQL
{
get
{
return #" SELECT fleetchecklist.*,
cl.ChecklistNo As CheckListNo,
v.VehicleOwnerID AS VehicleOwnerID,
v.VehicleOwner AS VehicleOwnerName,
v.Reg As VehicleReg,
t.TrailerOwnerID AS TrailerOwnerID,
t.TrailerOwner AS TrailerOwnerName,
t.Reg As TrailerReg,
vdlc.Description AS VehicleDriverLicenseClassName,
tdlc.Description AS TrailerDriverLicenseClassName,
m1.MaintenanceNo AS MaintenanceNo,
m1.Date AS Date
FROM fleetchecklist
LEFT JOIN maintenance m1 ON m1.LinkedID
LEFT JOIN Vehicle v ON m1.LinkedID = v.ID
LEFT JOIN Trailer t ON m1.LinkedID = t.ID
left join Employee ve ON v.VehicleOwnerID = ve.ID
LEFT JOIN Employee te ON t.TrailerOwnerID = te.ID
LEFT JOIN driverlicenseclass vdlc ON ve.DriverLicenseClassID = vdlc.ID
LEFT JOIN driverlicenseclass tdlc ON te.DriverLicenseClassID = tdlc.ID
LEFT JOIN GeneralSmall gs ON m1.TypeID = gs.ID
LEFT JOIN fleetchecklist cl ON m1.ChecklistID = cl.ID
WHERE m1.Company_ID = ?compid ";
}
}
I get the error:
Column 'CheckListID' does not belong to table .
and when I try add code m1.ChecklistID As CheckListID, for the CheckListID into the SQL I get the error:
Object cannot be cast from DBNull to other types.
The error happens in this method on the CheckListID line:
protected override void FillObject(DataRow dr)
{
ID = Convert.ToInt32(dr["ID"]);
CheckListID = Convert.ToInt32(dr["CheckListID"]);
LinkedItemID = Convert.ToInt32(dr["LinkedItemID"]);
ItemTitle = Convert.ToString(dr["ItemTitle"]);
Checked = Convert.ToBoolean(dr["Checked"]);
Defect = Convert.ToBoolean(dr["Defect"]);
Resolved = Convert.ToBoolean(dr["Resolved"]);
ResolvedDate = dr["ResolvedDate"].DateTimeOrNull();
ResolvedBy = dr["ResolvedBy"].IntOrNull();
if(dr["Comment"] != DBNull.Value)
Comment = Convert.ToString(dr["Comment"]);
if (dr["ResolvedComment"] != DBNull.Value)
ResolvedComment = Convert.ToString(dr["ResolvedComment"]);
}

You are selecting from fleetchecklist then joining it again at the end. Also LEFT JOIN maintenance m1 ON m1.LinkedID isn't joining it on anything.
SELECT fleetchecklist.*,
cl.ChecklistNo As CheckListNo,
v.VehicleOwnerID AS VehicleOwnerID, v.VehicleOwner AS VehicleOwnerName, v.Reg As VehicleReg,
t.TrailerOwnerID AS TrailerOwnerID, t.TrailerOwner AS TrailerOwnerName, t.Reg As TrailerReg,
vdlc.Description AS VehicleDriverLicenseClassName,
tdlc.Description AS TrailerDriverLicenseClassName,
m1.MaintenanceNo AS MaintenanceNo, m1.Date AS Date
FROM fleetchecklist cl
LEFT JOIN maintenance m1 ON cl.ID = m1.ChecklistID
LEFT JOIN Vehicle v ON m1.LinkedID = v.ID
LEFT JOIN Trailer t ON m1.LinkedID = t.ID
LEFT JOIN Employee ve ON v.VehicleOwnerID = ve.ID
LEFT JOIN Employee te ON t.TrailerOwnerID = te.ID
LEFT JOIN driverlicenseclass vdlc ON ve.DriverLicenseClassID = vdlc.ID
LEFT JOIN driverlicenseclass tdlc ON te.DriverLicenseClassID = tdlc.ID
LEFT JOIN GeneralSmall gs ON m1.TypeID = gs.ID
WHERE m1.Company_ID = ?compid
Also without pointless Aliases
SELECT fleetchecklist.*,
cl.ChecklistNo,
v.VehicleOwnerID, v.VehicleOwner AS VehicleOwnerName, v.Reg As VehicleReg,
t.TrailerOwnerID, t.TrailerOwner AS TrailerOwnerName, t.Reg As TrailerReg,
vdlc.Description AS VehicleDriverLicenseClassName,
tdlc.Description AS TrailerDriverLicenseClassName,
m1.MaintenanceNo, m1.Date
FROM fleetchecklist cl
LEFT JOIN maintenance m1 ON cl.ID = m1.ChecklistID
LEFT JOIN Vehicle v ON m1.LinkedID = v.ID
LEFT JOIN Trailer t ON m1.LinkedID = t.ID
LEFT JOIN Employee ve ON v.VehicleOwnerID = ve.ID
LEFT JOIN Employee te ON t.TrailerOwnerID = te.ID
LEFT JOIN driverlicenseclass vdlc ON ve.DriverLicenseClassID = vdlc.ID
LEFT JOIN driverlicenseclass tdlc ON te.DriverLicenseClassID = tdlc.ID
LEFT JOIN GeneralSmall gs ON m1.TypeID = gs.ID
WHERE m1.Company_ID = ?compid

Related

How to make left join and group by in linq?

I want to join 3 tables 2 of them inner join one of them left join after that i want to make group by. However, it gives an error. How can I handle that ?
this is code :
var people = from u in db.User.ToList()
join o in db.Offer.ToList() on u.UserId equals o.UserID where o.Statu == "Accepted"
join oz in db.log.ToList() on new { x1 = u.UserId.ToString(), x2 = o.CampaignId.ToString() } equals new { x1 = oz.ID, x2 = oz.CampaignID } into ps
from tbl in ps.DefaultIfEmpty()
group new { u, o, tbl } by new { u.UserId, o.CampaignId, o.Target, tbl.ID} into grp
select new { Username = grp.Key.UserId, CampaignID= grp.Key.CampaignId, Target = grp.Key.Target, id = grp.Key.ID};
Error occurs when i use tbl in group by. But i need to use it. I think some values comes null so it gives an error. How can i handle this ?

T-SQL to LINQ query that has a case statement and a subquery in it

I'm a complete beginner in LINQ and I would like to convert this T-SQL query in LINQ
SELECT
CASE
WHEN D.IsBaseloadDefined = 1
THEN COUNT(D.DeviceID)
ELSE
(SELECT COUNT(DORG.DeviceID)
FROM DeviceOrganization DORG
INNER JOIN Organization ORG ON DORG.OrganizationID = ORG.OrganizationID
INNER JOIN BaseloadOrganization BO ON ORG.BaseloadOrganizationId = BO.OrganizationID
INNER JOIN Baseload BL ON BO.BaseloadID = BL.BaseloadID
WHERE DORG.DeviceID = D.DeviceID
AND BL.RecursUntil >= GETDATE()
GROUP BY DORG.DeviceID)
END AS [Nb of devices]
FROM DeviceOrganization DO
INNER JOIN Device D ON DO.DeviceID = D.DeviceID
LEFT JOIN BaseloadDevice BD ON D.DeviceID = BD.DeviceID
LEFT JOIN Baseload B ON BD.BaseloadID = B.BaseloadID AND B.RecursUntil >= GETDATE()
INNER JOIN OrganizationHierarchy OH ON DO.OrganizationID = OH.SubOrganizationID
WHERE OH.OrganizationID = 6
AND D.IsActive = 1
group by D.DeviceID, D.IsBaseloadDefined
I've seen this topic but I don't really understand the answer
The only thing I could do so far is this, and now I'm completly lost
from deviceO in _context.DeviceOrganizations
join d in _context.Devices on deviceO.DeviceID equals d.DeviceID
join bd in _context.BaseloadDevices on d.DeviceID equals bd.DeviceID
join b in _context.Baseloads on bd.BaseloadID equals b.BaseloadID
join oh in _context.OrganizationHierarchies on deviceO.OrganizationID equals oh.SubOrganizationID
where oh.OrganizationID == OrganizationId
where d.IsActive == true
where b.RecursUntil <= DateTime.Now
group d.DeviceID by d.DeviceID).Count()
Instead of get count of group
group d.DeviceID by d.DeviceID).Count()
you should save result in variable
var data = from deviceO in _context.DeviceOrganizations
join d in _context.Devices on deviceO.DeviceID equals d.DeviceID
join bd in _context.BaseloadDevices on d.DeviceID equals bd.DeviceID
join b in _context.Baseloads on bd.BaseloadID equals b.BaseloadID
join oh in _context.OrganizationHierarchies on deviceO.OrganizationID equals oh.SubOrganizationID
where oh.OrganizationID == OrganizationId
where d.IsActive == true
where b.RecursUntil <= DateTime.Now
and then you should do something like this:
//group by 2 properties
var result = data.GroupBy(d => new { d.DeviceID, d.IsBaseloadDefined })
.Select(g =>
{
//for each group we get IsBaseloadDefined property
var IsBaseloadDefined = g.Key.IsBaseloadDefined;
if (IsBaseloadDefined == 1)
{
return g.Count();
}
else
{
// here another select that return count:
//(SELECT COUNT(DORG.DeviceID)
//FROM DeviceOrganization DORG
// INNER JOIN Organization ORG ON DORG.OrganizationID = ORG.OrganizationID
//INNER JOIN BaseloadOrganization BO ON ORG.BaseloadOrganizationId = BO.OrganizationID
//INNER JOIN Baseload BL ON BO.BaseloadID = BL.BaseloadID
//WHERE DORG.DeviceID = D.DeviceID
//AND BL.RecursUntil >= GETDATE()
//GROUP BY DORG.DeviceID)
//in this query you should return Count() of group
return 1; //return group.Count() instead 1
}
});
I hope this helps you

Translate nested select of oracle query to linq

I was given an oracle query and am trying to translate it to linq. I have been successful up to the point of the inner select.
select distinct pm.projNumber, nvl(s.submission_nbr, ppo.submission_nbr) submission_nbr, nvl(ot.objectname, pot.objectname) objectname , wa.assigned, f.lname, f.fname
from wfassignment wa
join CodeTab c on c.codeid = wa.appr_stat
join projobject po on po.objectid = wa.objectid
join projmain pm on pm.projid = po.projid
join hhistory s on s.Prop_no = pm.Prop_No and s.Inst_Code = pm.Inst_Code and pm.System = 'foo' and s.mark = po.mark
left join objecttypes ot on ot.objecttype = po.objecttype and ot.system = pm.system
left join(
select a.mark, a.objecttype, a.submitdate, c.submission_nbr
from projobject a
join b on b.projid = a.projid
join c on c.Prop_no = b.Prop_No and c.Inst_Code = b.Inst_Code and b.System = 'foo' and c.mark = a.mark ) ppo on ppo.mark = s.parentmark
left join objecttypes pot on pot.objecttype = ppo.objecttype and pot.system = pm.system
join faculty f on f.unique_id = wa.unique_id
where wa.completed is null and wa.unique_id in ('foo', 'bar', 'foo', 'bar')
below is my C# code up until "left join (select... )"
var pageObject = (
from wa in db.WFASSIGNMENTs
join c in db.CODETABs on wa.APPR_STAT equals c.CODEID
join po in db.PROJOBJECTs on wa.OBJECTID equals po.OBJECTID
join pm in db.PROJMAINs on po.PROJID equals pm.PROJID
join s in db.HHISTORies on new { pm.PROP_NO, pm.INST_CODE, po.MARK } equals new { s.PROP_NO, s.INST_CODE, s.MARK }
join ot in db.OBJECTTYPES on new { OBJECTTYPE = po.OBJECTTYPE, pm.SYSTEM } equals new { OBJECTTYPE = ot.OBJECTTYPE1, ot.SYSTEM }
How do I translate the inner select to linq?
I pulled out the inner select into another variable and just joined that variable. Did the trick.

Incorrect values after SQL to LINQ convertion

I need to convert following SQL into LINQ
select
app.id,
app.name,
app.version,
s.application,
s.analysis,
s.behaviour,
(select count(ia.id)
from appInstalled ia
JOIN deviceUser ud ON ia.device_id = ud.device_id
where ia.app_id = app.id) as deviceCount,
max(alrt.alert_date)
from application app
left join score s on app.app_md5 = s.md5hash
left join alert alrt on app.id = alrt.app_id
where app.name like '%gpsnav%'
group by device;
This is what I've done so far
var appQuery = (from app in entities.applications
join score in entities.scores on app.app_md5 equals score.md5hash into appScore
join alrt in entities.alerts on app.id equals alrt.app_id into appAlerts
from s in appScore.DefaultIfEmpty()
from a in appAlerts.DefaultIfEmpty()
let deviceCount = (from iapp in entities.appInstalled
join ud in entities.deviceUser on iapp.device_id equals ud.device_id
where iapp.id == app.id
select iapp.id).Count()
where string.IsNullOrEmpty(searchTerm) || app.name.ToLower().Contains(searchTerm.ToLower())
select new
{
AppId = app.id,
AppName = app.name,
AppVersion = app.version,
AppScore = s.application,
Analysis = s.analysis,
Behavior = s.behaviour,
Devices = deviceCount,
AlertDate = a.alert_date
});
var grouped = from a in appQuery
group a by new
{
a.AppId,
a.AppName,
a.AppVersion,
a.AppScore,
a.Analysis,
a.Behavior,
a.Devices,
a.AlertDate
} into g
select new
{
g.Key.AppId,
g.Key.AppName,
g.Key.AppVersion,
g.Key.AppScore,
g.Key.Analysis,
g.Key.Behavior,
g.Key.Devices,
AlertDate = g.Max(x=>x.AlertDate)
};
The above LINQ works but the data is incorrect for Device and AlertDate. What I am missing in here? Also I am not getting max of AlertDate while grouping in LINQ.

entity framework query, how to select more than 1 table?

i have this query
var resultado = from c in conn.carrera
join u in conn.usuario on c.idusuario equals u.idusuario
join t in conn.texto on c.idtexto equals t.idtexto
where c.estatus == 1
select c;
how do i get something as it:
select c.*,u.*,t.eltexto from carrera c
join usuario u on c.idusuario =u.idusuario
join texto t on c.idtexto = t.idtexto
where c.estatus = 1
you could see in the query i am select c.*, u.* and t.col1, then
how can i get it in EF? because my first query gets only carrera.* but i need more data.
thanks
You could easily return a new object consisting all the properties of the three joined tables:
var resultado = from c in conn.carrera
join u in conn.usuario on c.idusuario equals u.idusuario
join t in conn.texto on c.idtexto equals t.idtexto
where c.estatus == 1
select new
{
c.prop_1,
c.prop_n,
u.prop_1,
u.prop_n,
t.prop_1,
t.prop_n
};
select c.*,u.*,t.eltexto from carrera c
join usuario u on c.idusuario =u.idusuario
join texto t on c.idtexto = t.idtexto
where c.estatus = 1
from c in Carrerra
join u in Usuario on c.idusuario equals u.idusuario
join t in Texto on c.idtexto equals t.idtexto
where c.estatus = 1
select new {
newcolumn1 = c.column1,
c.column2,
usercolumn1 = u.column1,
usercolumn2 = u.column2,
textcolumn = t.column1
}
if you want access to the objects themselves, then you could do
select new {
usario = u,
carrera = c,
texto = t
}
Carrera, Usario, and Texto refer to the Models in your Entity Framework container.

Categories