Converting complex SQL with FULL JOIN to Linq - c#

I am trying to convert a SQL statement to Linq/Entity Framework, and am having a difficult time. Below is the SQL.
SELECT
trust.FName,
trust.MName,
trust.LName
tla.Address,
tma.Address,
at.Descr
FROM CLIENTSSUITS cs
INNER JOIN TRUSTS trust ON trust.SSN = cs.CLIENT
FULL JOIN ADV_TYPES at ON at.CODE = trust.AT
LEFT OUTER JOIN CLIENTADDRESSES tla ON tla.SSN = trust.SSN AND tla.ID = 'L'
LEFT OUTER JOIN CLIENTADDRESSES tma ON tma.SSN = trust.SSN AND tma.ID = 'M'
WHERE cs.PRIMARY = w AND SecondaryRole = x AND cs.ID = y AND cs.Rev = z AND cs.DELETED = 0
GROUP BY trust.FName,
trust.MName,
trust.LName,
tla.Address,
tma.Address,
at.Descr
The FULL JOIN and the GROUP BY seem to be what I'm struggling most with. I've reviewed this SO answer and I understand how to execute a FULL JOIN on its own, but can't figure out how to integrate that into the larger overall query.
TYA for any answers.

Try this
using(var ctx = new Dbcontext())
{
var list = (
from cs in ctx.CLIENTSSUITS
join trust in ctx.TRUSTS on cs.CLIENT equals trust.CLIENT
join at in ctx.ADV_TYPES on at.CODE equals trust.AT into temp from temp.DefaultIfEmpty()
join tla1 in ctx.CLIENTADDRESSES on tla.SSN equals trust.SSN && tla.ID = 'L' into temp2 from subtla1 in temp2.DefaultIfEmpty()
join tla2 in ctx.CLIENTADDRESSES on tla2.SSN equals trust.SSN && tla2.ID = 'M' into temp3 from subtla2 in temp3.DefaultIfEmpty()
where (cs.PRIMARY = w && ?.SecondaryRole = x && cs.ID = y && cs.Rev = z && cs.DELETED = 0)
select new
{
FName = trust.FName,
MName = trust.MName,
LName = trust.LName
LAddress = tla.Address,
MAddress = tma.Address,
Descr = at.Descr
}).ToList();
}
//if the list contains the right result then you can easily group it with this code
var results = list.GroupBy(x => new {
x.FName, x.MName, x.LName, x.LAddress, x.MAddress, Descr
});

Related

How to use group by with inner join in LINQ

I'm trying to write a LINQ for the below query,
Select DIS.iDataItemID, DIS.iDataItemCurrentStatusID, DI.iDataTypeID,
DI.iEmployeeID, DI.iEmployerID, DI.iLinkID, DI.iSystemID, DI.sData,
DI.sEmployerCode, DI.sRecieptID, COunt(*)
from DataItem DI
INNER JOIN DataItemStatus DIS ON DIS.iDataItemID =
DI.iDataItemID
INNER JOIN RefDataItemStatus ON DIS.iDataItemCurrentStatusID
= RefDataItemStatus.iDataItemStatusID
AND DIS.iDataItemCurrentStatusID = 1 AND DI.iDataTypeID = 8
GROUP BY DIS.iDataItemID, DIS.iDataItemCurrentStatusID, DI.iDataTypeID,
DI.iEmployeeID, DI.iEmployerID, DI.iLinkID, DI.iSystemID, DI.sData,
DI.sEmployerCode, DI.sRecieptID
I have written the LINQ as below, Need to know how to use Group by on this,
from dataItem in msaDBContext.DataItem
join dataItemStatus in msaDBContext.DataItemStatus on dataItem.iDataItemID equals dataItemStatus.iDataItemID
join refDataItemStatus in msaDBContext.RefDataItemStatus on dataItemStatus.iDataItemCurrentStatusID equals refDataItemStatus.iDataItemStatusID
where dataItemStatus.iDataItemCurrentStatusID == _processingStatus.iDataItemStatusID && dataItem.iDataTypeID == _dataType.iDataTypeID
select new
{
iDataItemID = dataItem.iDataItemID,
iDataItemCurrentStatusID = dataItemStatus.iDataItemCurrentStatusID,
iDataTypeID = dataItem.iDataTypeID,
iLinkID = dataItem.iLinkID,
biRowVersion = dataItem.biRowVersion,
sData = dataItem.sData,
iEmployeeID = dataItem.iEmployeeID,
iEmployerID = dataItem.iEmployerID,
sEmployerCode = dataItem.sEmployerCode,
iSystemID = dataItem.iSystemID,
sReceiptID = dataItem.sRecieptID
};

How to do concat or group by in linq? I am getting multiples values want to concat the data by ','

my Query:
var s = entities.Doctors.SingleOrDefault(x => x.AreaId == id);
var z = (from x in entities.Doctors
join y in entities.Areas on x.AreaId equals y.AreaId
join s1 in entities.Availabilties on s.D_Id equals s1.DoctorId
join s2 in entities.Eductions on s.D_Id equals s2.DoctorId
join s3 in entities.DoctorSpecialities on s.D_Id equals s3.DoctorId
join s4 in entities.Specialities on s3.SpecialityId equals s4.SpecialityId
join s5 in entities.DaysDetails on s1.DaysId equals s5.DaysId
join s6 in entities.Degrees on s2.DegreeId equals s6.DegreeId
where x.AreaId.Equals(id)
select new DoctorDisplay
{
D_name = x.D_Name,
D_address = x.D_Address,
D_Area = y.AreaName,
D_Contact1 = x.D_Contactone,
D_Contact2 = x.D_Contacttwo,
D_fax = x.D_Faxno,
D_SpecialityName = s4.SpecialityName,
D_Availstarttime = s1.StartTime,
D_Availlasttime = s1.LastTime,
D_Availday= s5.DaysName,
D_DegreeName = s6.DegreeName,
D_Awards = x.D_Address,
D_Status = x.D_Status
}).ToList();
****Getting Output****
[{"D_name":"Shanu","D_address":"block123","D_Area":"Manama","D_Contact1":"123","D_Contact2":"456","D_fax":"789","D_SpecialityName":"Dietician","D_Availstarttime":"9PM","D_Availlasttime":"11PM","D_Availday":"Sunday","D_DegreeName":"MBBS","D_Awards":"block123","D_Status":"Available"},{"D_name":"Shanu","D_address":"block123","D_Area":"Manama","D_Contact1":"123","D_Contact2":"456","D_fax":"789","D_SpecialityName":"Dietician","D_Availstarttime":"9PM","D_Availlasttime":"11PM","D_Availday":"Sunday","D_DegreeName":"Dentistdegree","D_Awards":"block123","D_Status":"Available"},{"D_name":"Shanu","D_address":"block123","D_Area":"Manama","D_Contact1":"123","D_Contact2":"456","D_fax":"789","D_SpecialityName":"Ayurveda","D_Availstarttime":"9PM","D_Availlasttime":"11PM","D_Availday":"Sunday","D_DegreeName":"MBBS","D_Awards":"block123","D_Status":"Available"},{"D_name":"Shanu","D_address":"block123","D_Area":"Manama","D_Contact1":"123","D_Contact2":"456","D_fax":"789","D_SpecialityName":"Ayurveda","D_Availstarttime":"9PM","D_Availlasttime":"11PM","D_Availday":"Sunday","D_DegreeName":"Dentistdegree","D_Awards":"block123","D_Status":"Available"},{"D_name":"Shanu","D_address":"block123","D_Area":"Manama","D_Contact1":"123","D_Contact2":"456","D_fax":"789","D_SpecialityName":"Dietician","D_Availstarttime":"4AM","D_Availlasttime":"11AM","D_Availday":"Monday","D_DegreeName":"MBBS","D_Awards":"block123","D_Status":"Available"},{"D_name":"Shanu","D_address":"block123","D_Area":"Manama","D_Contact1":"123","D_Contact2":"456","D_fax":"789","D_SpecialityName":"Dietician","D_Availstarttime":"4AM","D_Availlasttime":"11AM","D_Availday":"Monday","D_DegreeName":"Dentistdegree","D_Awards":"block123","D_Status":"Available"},{"D_name":"Shanu","D_address":"block123","D_Area":"Manama","D_Contact1":"123","D_Contact2":"456","D_fax":"789","D_SpecialityName":"Ayurveda","D_Availstarttime":"4AM","D_Availlasttime":"11AM","D_Availday":"Monday","D_DegreeName":"MBBS","D_Awards":"block123","D_Status":"Available"},{"D_name":"Shanu","D_address":"block123","D_Area":"Manama","D_Contact1":"123","D_Contact2":"456","D_fax":"789","D_SpecialityName":"Ayurveda","D_Availstarttime":"4AM","D_Availlasttime":"11AM","D_Availday":"Monday","D_DegreeName":"Dentistdegree","D_Awards":"block123","D_Status":"Available"}]
Group_concat on the basis of Education Id, DoctorspecialitiesID, Avaibilities Id,
Image of Input and desire Output
Looking at you example output, it looks less like you want to "concat the data by ','" as much as you want to convert it to JSON.
Inwhichcase, you'd probably be better off using a tool like Newtonsoft's JSON.NET
UPDATE (based on comments):
Assume doctors is the result of the query given in question.
var output =
from d in doctors
group d by new { d.D_NAME, d.D_Area } into dg
select new DoctorDisplay
{
D_NAME = dg.Key.D_NAME,
D_Area = dg.Key.D_Area,
D_SpecialityName = String.Join(",", dg.Select(d => d.D_SpecialityName).Distinct()),
D_DegreeName = String.Join(",", dg.Select(d => d.D_DegreeName).Distinct())
};

Complex LINQ-TO-SQL solution.......or just my inexperience?

Learning LINQ-TO-SQL and getting on well. But now I think I'm at a "walk before you run" stage.
This LINQ-TO-SQL works:
var arr = (from up in db.fad_user_physician
join u in db.fad_user on up.userID equals u.userID
where up.physicianID.ToString() == userIdString
select new ListOfUsersForPhysician
{
userID = u.userID,
forename = u.forename,
surname = u.surname,
email = u.email,
gender = u.gender,
dobStr = u.dob.ToString()
}).ToList();
I now want to incorporate a calculation into it.
The TSQL (which works) is thus:
(Note: physicianID is the only thing I have to work with, obtained from their logon details)
EDITED 17/2/16 16:03:
select fuf.userid,
((CAST(COUNT(fuf.userid)AS DECIMAL(6,2))/
(DATEDIFF(dd,fu.dateJoined,GETDATE())*5))*100) AS 'percent'
from fad_user_physician fup
inner join fad_user fu on fu.userID = fup.userID
inner join fad_userFoods fuf on fuf.userID = fu.userID
inner join fad_food ff on ff.foodID = fuf.FoodID
where fup.physicianID = '5C46F531-FF64-4254-8072-F291627ABD3D'
AND fuf.quantityAmount >= ff.portionSize
group by fuf.userID,fu.dateJoined
So basically I want a list of users for a physician, with a % calculation as well.
I've googled this for many an hour, tutorials and all. But just getting bogged down in the complexity of LINQ-TO-SQL (for the newbie!)
Should I be using a LET statement?
Should I be using a LINQ-TO-SQL statement in the select part?
I tried:
let maxPos = DbFunctions.DiffDays(u.dateJoined, DateTime.Now)*5
let temp = (from fuf in db.fad_userFoods
join ff in db.fad_food on fuf.foodID equals ff.foodID
join fu in db.fad_user on fuf.userID equals fu.userID
where fuf.userID.ToString() == userIdString
&& fuf.quantityAmount >= ff.portionSize
group fuf by new {num = fuf.userID} into e
select new {total = e.Key.num}).Count()
maxpos gives me the correct value.
But temp gives me 0.
Any guidance would be appreciated!
Thanks in advance.
You should be able to do the following using navigation properties
var results = from fu in db.fad_user
from fuf in fu.fad_userFoods
from ff in fuf.fad_foods
where fuf.userId = someGuid && fuf.quantityAmount >= ff.portionSize
group fu.userid by new {fuf.userID, fu.dateJoined} into g
select new
{
g.Key.userid,
Percent = 100 * ((decimal)(g.Count())
/ (DbFunctions.DiffDays(g.Key.dateJoined, DateTime.Now) * 5))
};
or using join if you don't have navigation properties
var results = from fu in db.fad_user
join fuf in db.fad_userFoods on fuf.userID equals fu.userID
join ff in db.fad_food on fuf.foodID equals ff.foodID
where fuf.userId = someGuid && fuf.quantityAmount >= ff.portionSize
group fu.userid by new {fuf.userID, fu.dateJoined} into g
select new
{
g.Key.userid,
Percent = 100 * ((decimal)(g.Count())
/ (DbFunctions.DiffDays(g.Key.dateJoined, DateTime.Now) * 5))
};

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.

Count with left outer join in linq to entites

I'm having trouble understanding a left outer join count in Linq to Entities.
My query is:
SELECT Locations.LocationId, Locations.LocationName, LocationPrizes.PrizeId, LocationPrizes.PrizeQuantity, Prizes.PrizeName, ISNULL(COUNT(WonPrizes.WonPrizeId), 0) AS WonPrizes
FROM Locations
INNER JOIN LocationPrizes ON Locations.LocationId = LocationPrizes.LocationId INNER JOIN Prizes ON LocationPrizes.PrizeId = Prizes.PrizeId
LEFT OUTER JOIN WonPrizes ON Locations.LocationId = WonPrizes.LocationId AND Prizes.PrizeId = WonPrizes.PrizeId
GROUP BY Locations.LocationId, Locations.LocationName, LocationPrizes.PrizeId, LocationPrizes.PrizeQuantity, Prizes.PrizeName
My Linq is:
var locationPrizes = from l in context.Locations
select new
{
l.LocationId,
l.LocationName,
Prizes = from o in l.LocationPrizes
select new
{
o.PrizeId,
o.PrizeQuantity,
o.Prize.PrizeJson
}
};
I can't get the count on teh left outer join part working correctly. Any pointers?
If you happen to have an association from LocationPrizes -> WonPrizes you can just do this:
var locationPrizes =
from l in context.Locations
select new
{
l.LocationId,
l.LocationName,
Prizes =
from o in l.LocationPrizes
select new
{
o.PrizeId,
o.PrizeQuantity,
o.Prize.PrizeJson
WonPrizes = o.WonPrizes.Count();
}
};
If not, this will work too (works for me with the minor edits below):
var locationPrizes =
from l in context.Locations
select new
{
l.LocationId,
l.LocationName,
Prizes =
from o in l.LocationPrizes
select new
{
o.PrizeId,
o.PrizeQuantity,
o.Prize.PrizeJson
WonPrizes =
(from w in context.WonPrizes
where w.PrizeId == o.PrizeId
&& w.LocationId == l.LocationId
select w)
.Count()
}
};

Categories