how to convert a sql query into linq LEFT OUTER JOIN - sql

This is the SQL query that returns the data I need:
SELECT
E.DESCS AS EMP, C.USERNAME,
(SELECT A.DESCS
FROM CAD_COLABORADOR H, CAD_DEPT A
WHERE H.DEPT = A.ID AND H.ID = C.ID) AS DEPT,
D.IDENTIFICADOR, D.MODELO, O.DESCS AS OFFICE,
D.K_OFFICE AS 'KEY OFFICE', S.DESCS AS SO, D.K_SO AS 'KEY SO'
FROM
IN_DESKTOP D
LEFT OUTER JOIN
CAD_COLABORADOR C ON D.ID = C.DESKTOP
INNER JOIN
CAD_EMP E ON D.EMP = E.ID
INNER JOIN
CAD_OFFICE O ON D.V_OFFICE = O.ID
INNER JOIN
CAD_SO S ON D.V_SO = S.ID ;
This is the linq expression I'm using plus has some inconsistencies since it returns the most data are not exactly the same as the SQL query:
var result = from desk in db.IN_DESKTOP
join co in db.CAD_COLABORADOR on desk.id equals co.id into egroup
from co in egroup.DefaultIfEmpty()
join e in db.CAD_EMP on desk.emp equals e.id
join o in db.CAD_OFFICE on desk.v_office equals o.id
join s in db.CAD_SO on desk.v_so equals s.id
select new
{
Empresa = e.descs,
UserName = co.username,
Departamento = co.CAD_DEPT.descs,
Identificador = desk.identificador,
Modelo = desk.modelo ,
Offices = o.descs,
KeyOfice = desk.k_office,
KeySo = desk.k_so
};

A left outer join in C# is just a GroupJoin followed by a SelectMany with default if empty - I've been using this extension for lambda expressions
public static class LinqExtension
{
public static IEnumerable<TResult> LeftOuterJoin<TLeft, TRight, TKey, TResult>(
this IEnumerable<TLeft> leftCollection, IEnumerable<TRight> rightCollection,
Func<TLeft, TKey> leftKey, Func<TRight, TKey> rightKey,
Func<TLeft, TRight, TResult> result)
{
return leftCollection.GroupJoin(rightCollection,
leftKey,
rightKey,
(leftObject, rightObject) => new { leftObject, rightObject })
.SelectMany(x => x.rightObject.DefaultIfEmpty(),
(l, r) => new { left = l.leftObject, right = r })
.Select(x => result.Invoke(x.left, x.right));
}
}

Related

Hibernate generates syntactically incorrect SQL

I have the following entity:
#Entity
#Table(name = "follow_ups")
#Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
#Access(AccessType.FIELD)
public class FollowUp extends EntityObject {
private static final long serialVersionUID = -1343114665843716990L;
#ManyToOne(optional = false)
#JoinColumn(name = "contact_id")
private Contact contact;
#ManyToOne(optional = true)
#JoinColumn(name = "dossier_id")
private Dossier dossier;
#ManyToOne(optional = true)
#JoinColumn(name = "website_item_id")
private WebsiteItem websiteItem;
#ManyToOne(optional = true, fetch = FetchType.LAZY)
#JoinColumn(name = "invoice_id")
private Invoice invoice;
#Column(name = "message_date")
#OrderBy("message_date DESC")
private Date messageDate;
#Column(name = "message")
private String message;
#ManyToOne
#JoinColumn(name = "creator")
private BackendUser creator;
public Contact getContact() {
return contact;
}
public void setContact(Contact contact) {
this.contact = contact;
}
public Dossier getDossier() {
return dossier;
}
public void setDossier(Dossier dossier) {
this.dossier = dossier;
}
public WebsiteItem getWebsiteItem() {
return websiteItem;
}
public void setWebsiteItem(WebsiteItem websiteItem) {
this.websiteItem = websiteItem;
}
public Invoice getInvoice() {
return invoice;
}
public void setInvoice(Invoice invoice) {
this.invoice = invoice;
}
public BackendUser getCreator() {
return creator;
}
public void setCreator(BackendUser creator) {
this.creator = creator;
}
public Date getMessageDate() {
return messageDate;
}
public void setMessageDate(Date messageDate) {
this.messageDate = messageDate;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
When using a criteria that checks anything on the invoice, invoice.id for instance, or when the invoice is fetched eagerly, the following sql is created (this is only one of many queries that it executes):
SELECT vatdetails0_.invoice_id AS invoice_5_40_1_,
vatdetails0_.id AS id1_39_1_,
vatdetails0_.id AS id1_39_0_,
vatdetails0_.invoice_id AS invoice_5_39_0_,
vatdetails0_.invoice_vat_type AS invoice_2_39_0_,
vatdetails0_.vat AS vat3_39_0_,
vatdetails0_.vat_amount AS vat_amou4_39_0_
FROM invoice_vat_details vatdetails0_
WHERE vatdetails0_.invoice_id IN
(SELECT invoice11_.id
FROM website_lots l
WHERE l.website_item_id = websiteite14_.id
) = 0 THEN websiteite14_.end_date ELSE
(SELECT MAX(l.enddate)
FROM website_lots l
WHERE l.website_item_id = websiteite14_.id
)
END THEN
CASE
WHEN (SELECT COUNT(*)
FROM website_lots wl
INNER JOIN website_lots_auction wla
ON wl.id = wla.id
WHERE wla.status = 'AVAILABLE'
AND wl.website_item_id = websiteite14_.id) =
(SELECT COUNT(*)
FROM website_lots wl
INNER JOIN website_lots_auction wla
ON wl.id = wla.id
WHERE wl.website_item_id = websiteite14_.id
)
THEN 5
WHEN (SELECT COUNT(*)
FROM website_lots wl
INNER JOIN website_lots_auction wla
ON wl.id = wla.id
WHERE wla.status = 'AVAILABLE'
AND wl.website_item_id = websiteite14_.id) = 0
THEN 7
ELSE 6
END WHEN now() < websiteite14_.start_date THEN 2 WHEN now() >= websiteite14_.start_date THEN 1 ELSE -1
END WHEN websiteite14_.type = 'RENT' THEN 1 ELSE
CASE
WHEN (SELECT COUNT(*)
FROM website_lots
INNER JOIN lots
ON lots.id = website_lots.lot_id
WHERE website_lots.website_item_id = websiteite14_.id) =
(SELECT COUNT(*)
FROM website_lots
INNER JOIN lots
ON lots.id = website_lots.lot_id
WHERE lots.status = 'SOLD'
AND website_lots.website_item_id = websiteite14_.id
)
THEN 3
ELSE 1
END
END AS formula10_12_,
CASE
WHEN (SELECT COUNT(*)
FROM website_lots wl
LEFT JOIN website_lots_sale wls
ON wl.id=wls.id
LEFT JOIN website_lots_auction wla
ON wl.id =wla.id
WHERE wl.website_item_id = websiteite14_.id
AND (wls.status <> 'AVAILABLE'
OR wla.status <> 'AVAILABLE')) = 0
THEN 'ALL'
WHEN (SELECT COUNT(*)
FROM website_lots wl
LEFT JOIN website_lots_sale wls
ON wl.id=wls.id
LEFT JOIN website_lots_auction wla
ON wl.id =wla.id
WHERE wl.website_item_id = websiteite14_.id
AND (wls.status = 'AVAILABLE'
OR wla.status = 'AVAILABLE')) = 0
THEN 'NONE'
ELSE 'PART'
END AS formula11_12_,
CASE
WHEN (SELECT COUNT(*)
FROM website_lots l
WHERE l.website_item_id = websiteite14_.id) = 0
THEN websiteite14_.end_date
ELSE
(SELECT MAX(l.enddate)
FROM website_lots l
WHERE l.website_item_id = websiteite14_.id
)
END AS formula12_12_,
CASE
WHEN (SELECT COUNT(*)
FROM website_lots l
WHERE l.website_item_id = websiteite14_.id) = 0
THEN NULL
ELSE
(SELECT MAX(l.soldDate)
FROM website_lots l
WHERE l.website_item_id = websiteite14_.id
)
END AS formula18_12_,
websiteite14_.type AS type1_80_12_
FROM follow_ups this_
INNER JOIN contacts contact2_
ON this_.contact_id=contact2_.id
LEFT OUTER JOIN frontend_users frontendus3_
ON contact2_.id=frontendus3_.contact_id
LEFT OUTER JOIN backend_users backenduse4_
ON this_.creator=backenduse4_.id
LEFT OUTER JOIN dossiers dossier5_
ON this_.dossier_id=dossier5_.id
LEFT OUTER JOIN backend_users backenduse6_
ON dossier5_.applier_backend_user_id=backenduse6_.id
LEFT OUTER JOIN backend_users backenduse7_
ON dossier5_.owner_backend_user_id=backenduse7_.id
LEFT OUTER JOIN commissions commission8_
ON dossier5_.id=commission8_.dossier_id
LEFT OUTER JOIN commission_brackets commission9_
ON commission8_.id=commission9_.commission_id
LEFT OUTER JOIN contacts contact10_
ON commission8_.contact_id=contact10_.id
LEFT OUTER JOIN invoices invoice11_
ON this_.invoice_id=invoice11_.id
LEFT OUTER JOIN invoiceContacts invoicecon12_
ON invoice11_.id=invoicecon12_.invoice_id
LEFT OUTER JOIN contacts contact13_
ON invoicecon12_.contact_id=contact13_.id
LEFT OUTER JOIN website_items websiteite14_
ON this_.website_item_id=websiteite14_.id )
This query is incorrect, generated error is about the first THEN keyword which can not be used at that position, and I have never had hibernate do this before. On the internet is not that much information to find about hibernate generating a faulty query.
Criteria used is the simplest case:
session.createCriteria(getEntityClass())
What can be wrong and should I check out?
How can I dive into hibernate to see what the problem is?
Maybe it should be logged as a hibernate bug?
Used hibernate version is: 4.3.10.Final
Dialect used: POSTGRESQL.

SQL to LINQ query equivalent

Hello I need to crate linq query from this SQL:
SQL:
select
p.id,
p.Name,
sum(h.Hour)
from
dbo.Hour h
INNER JOIN dbo.ProjectView p ON h.ProjectId = p.Id
WHERE
h.PeopleId = 7999
group by
p.Name, p.Id
LINQ: I tried this but it is not the same:
var query = from hours in _hourRepository.GetAll()
join proj in _projectRepository.GetAll() on hours.ProjectId equals proj.Id
where hours.PeopleId == personId
group hours by new { proj.Id, proj.Name, proj.Flag, hours.Hours } into g
select new PopleProjectsSumDto
{
Id = g.Key.Id,
Name = g.Key.Name,
Flag = g.Key.Flag,
Hours = g.Sum(h => h.Hours)
};
OK i find solution by removing hours from group:
LINQ:
var query = from hours in _hourRepository.GetAll()
join proj in _projectRepository.GetAll() on hours.ProjectId equals proj.Id
where hours.PeopleId == personId
group hours by new { proj.Id, proj.Name, proj.Flag } into g
select new PopleProjectsSumDto
{
Id = g.Key.Id,
Name = g.Key.Name,
Flag = g.Key.Flag,
Hours = g.Sum(h => h.Hours)
};

How can I count results from one into a group with different conditions? Linq query

select
count(pat.ID) as PatientEmail,
count(a.ID) as AlaEmails,
count(t.ID) as TrusteeEmails,
count(s.ID) + 1 as SpecialistEmail
from [dbo].[Users] as u
left join [dbo].[Patients] as pat
on u.ID = pat.ID and u.Email != 'email#gmail.com'
left join [dbo].[Patients] as a
on u.ID = a.ID and u.Email = 'email#gmail.com'
left join [dbo].[Trusteehips]as t
on u.ID = t.Trustee_ID
left join [dbo].[Specialists] as s
on u.ID = s.ID and u.Email != 'email#gmail.com'
where u.Active = 1 and u.Deleted = 0
public class UserEmails
{
public int PatientEmail { get; set; }
public int AlaEmails { get; set; }
public int TrusteeEmails { get; set; }
}
public ActionResult ReportByEmail()
{
var res = from u in context.Users
join p in context.Patients
on u.ID equals p.ID into pGroup
join t in context.Trusteeships
on u.ID equals t.Trustee.ID into tGroup
select new UserEmails
{
PatientEmail = pGroup.Count(g => g.Email != "email#gmail.com"),
AlaEmails = pGroup.Count(g => g.Email = "email#gmail.com"),
TrusteeEmails = tGroup.Count()
};
return View(res);
I tried to write this Linq code but it didn't work!
My count result is not shown in one row, I wrote code with same syntax (Group.Count()) and it worked fine, but here it didn't work!

SQL to LINQ Group by convertion

I have an SQL statement and I want to convert it to LINQ. The problem now is that I don't know how to group by it in LINQ.
Here is the code.
In SQL
select plp.ProspectsListID, p.Prospect_PII_Key
from ProspectListProspect plp
join Prospects p
on p.ProspectsID = plp.ProspectsID
group by plp.ProspectsListID,p.Prospect_PII_Key
In LINQ
var list1 = from plp in GetDataContext.SQLDataContext.GetTable<DataAccess.ProspectListProspect>()
join p in GetDataContext.SQLDataContext.GetTable<DataAccess.Prospect>()
on plp.ProspectsID equals p.ProspectsID
select new
{
ProspectID = plp.ProspectsListID,
Prospect_PII_Key = p.Prospect_PII_Key
};
thanks
Jason
tyr this
var list1 = from item in
(
from plp in GetDataContext.SQLDataContext.GetTable<DataAccess.ProspectListProspect>()
join p in GetDataContext.SQLDataContext.GetTable<DataAccess.Prospect>()
on plp.ProspectsID equals p.ProspectsID
select new
{
ProspectID = plp.ProspectsListID,
Prospect_PII_Key = p.Prospect_PII_Key
}
)
group item by new {item.ProspectID ,item.Prospect_PII_Key } into grp
select new
{
ProspectID = grp.ProspectsListID,
Prospect_PII_Key = grp.Prospect_PII_Key
}
;
Check this
var list1 = from plp in GetDataContext.SQLDataContext.GetTable<DataAccess.ProspectListProspect>()
join p in GetDataContext.SQLDataContext.GetTable<DataAccess.Prospect>()
on plp.ProspectsID equals p.ProspectsID
Group By Key = New With {plp.ProspectsListID,p.Prospect_PII_Key} Into Group
Select Group;
var list1 = from plp in GetDataContext.SQLDataContext.GetTable<DataAccess.ProspectListProspect>()
join p in GetDataContext.SQLDataContext.GetTable<DataAccess.Prospect>()
on plp.ProspectsID equals p.ProspectsID
group p by new {plp.ProspectsListID,p.Prospect_PII_Key} into g
select new
{
ProspectID = g.Key.ProspectsListID,
Prospect_PII_Key = g.Key.Prospect_PII_Key
};

Need Linq equivalent

Help in find the Linq equivalent on the below sql query:
select sum(weight) from (
select weight from pers p
join list l on l.persindex= p.persindex
group by p.persindex,weight) a
from p in context.pers
join l in context.list on l.persindex equals p.persindex
group by new
{ p.persindex,
l.weight
} into myGroup
select new()
{ Key = myGroup.Key,
GroupSum = myGroup.sum(x=>x.weight)
}
I guess that's what you need:
public int CalcWeight(IEnumerable<Person> pers, IEnumerable<Person> list)
{
return
pers
.Join(list, p=>p.PersIndex, l=>l.PersIndex, (p, l) => new {p.PersIndex, l.Weight})
.GroupBy( a => new {a.PersIndex, a.Weight})
.Sum(group=>group.Key.Weight);
}
Data class Person is decalerd like this:
public class Person
{
public int PersIndex;
public int Weight;
}
VB.NET version
Dim customerList = From p In pers
Group Join l In list On
p.persindex Equals l.persindex
Into joineddata = Group,
TotalOweight = Sum(p.weight)
Select p.persindex, TotalOweight
Try : Linquer SQL to LINQ convertion tool :
from p in pers
joins l in list on l.persindex equals p.persindex
group by new {p.persindex,l.weight } into grp
select new { sum = grp.sum(x=>x.weight)}