entity framework multi column - c#

In sqlcommand I have this:
SELECT *
FROM cliente c
LEFT JOIN abono a on
c.idcliente = a.idcliente
and (a.estatus = 1 or a.estatus = null)
LEFT JOIN usuario u on
a.creadopor = u.idusuario
WHERE c.estatus = 1
We know this is not the same than this:
SELECT *
FROM cliente c
LEFT JOIN abono a on
c.idcliente = a.idcliente
LEFT JOIN usuario u on
a.creadopor = u.idusuario
WHERE c.estatus=1
and (a.estatus = 1 or a.estatus = null)
How can I do the first query in entity framework?
the second query in entity framework is it
from c in Conexion.conexion.conect.cliente
join a in Conexion.conexion.conect.abono
on c.idcliente equals a.idcliente into alj
from a in alj.DefaultIfEmpty()
join u in Conexion.conexion.conect.usuario
on a.creadopor equals u.idusuario into ulj
from u in ulj.DefaultIfEmpty()
where c.estatus == 1
&& (a.estatus == 1 || a.estatus == null)
but i could not get the first query

This does the trick:
from c in Conexion.conexion.conect.cliente
join a in Conexion.conexion.conect.abono.Where(x.estatus == 1 || x.estatus == null)
on c.idcliente equals a.idcliente into alj
from a in alj.DefaultIfEmpty()
join u in Conexion.conexion.conect.usuario
on a.creadopor equals u.idusuario into ulj
from u in ulj.DefaultIfEmpty()
where c.estatus == 1

Related

Join multiple columns from the same table using Linq

I would like to convert following sql query into Linq to SQL
select distinct r.CompanyLogo, j.JobName, j.JobId, ur.UserId, r.JobSeekerID
, ur.FirstName, j.JobType, j.JobCareerLevel, j.JobLocation
from UserInterest m
join job j on m.FunctionalId = j.FunctionId or m.Careerlevel = j.CarrerLevelId or m.SalId = j.SalaryRangeId
join UserRegistration ur on j.UserId = ur.UserId
join EmplrRegistration r on j.UserId = r.JobSeekerID
where m.Status = 1 and m.UserId = 1
going through this I have so far tried following which didn't work out
var list = (from m in entities.UserInterests
from j in entities.Jobs
where m.FunctionalId == j.FunctionId || m.SalId == j.SalaryRangeId || m.Careerlevel == j.CarrerLevelId
&& m.Status == true && m.UserId == 1
join ur in entities.UserRegistrations on m.UserId equals ur.UserId
join r in entities.EmplrRegistrations on m.UserId equals r.JobSeekerID
select new { r.CompanyLogo, j.JobName, j.JobId, ur.UserId, r.JobSeekerID
, ur.FirstName, j.JobType, j.JobCareerLevel, j.JobLocation }).Distinct().ToList();
Edit:
following query is being generated against Svyatoslav Danyliv answer which is returning 7 rows instead of 6
SELECT 1 AS [C1], [Extent4].[CompanyLogo] AS [CompanyLogo], [Extent2].[JobName] AS [JobName]
,[Extent2].[JobId] AS [JobId], [Extent3].[UserId] AS [UserId]
,[Extent4].[JobSeekerID] AS [JobSeekerID], [Extent3].[FirstName] AS [FirstName]
,[Extent2].[JobType] AS [JobType], [Extent2].[JobCareerLevel] AS [JobCareerLevel]
,[Extent2].[JobLocation] AS [JobLocation]
FROM [dbo].[UserInterest] AS [Extent1]
INNER JOIN [dbo].[Job] AS [Extent2] ON ([Extent1].[FunctionalId] = [Extent2].[FunctionId])
OR (([Extent1].[FunctionalId] IS NULL) AND ([Extent2].[FunctionId] IS NULL))
OR ([Extent1].[Careerlevel] = [Extent2].[CarrerLevelId])
OR (([Extent1].[Careerlevel] IS NULL) AND ([Extent2].[CarrerLevelId] IS NULL))
OR ([Extent1].[SalId] = [Extent2].[SalaryRangeId])
OR (([Extent1].[SalId] IS NULL)
AND ([Extent2].[SalaryRangeId] IS NULL))
INNER JOIN [dbo].[UserRegistration] AS [Extent3] ON [Extent2].[UserId] = [Extent3].[UserId]
INNER JOIN [dbo].[EmplrRegistration] AS [Extent4] ON [Extent2].[UserId] = [Extent4].[JobSeekerID]
WHERE (1 = [Extent1].[Status]) AND (1 = [Extent1].[UserId])
Join which contains not just AND expressions is possible via from x in entities.Where(x => ..). You have did that partially and made mistake in where condition.
Corrected query, looks the same as original SQL
var query =
from m in entities.UserInterests
from j in entities.Jobs.Where(j =>
m.FunctionalId != null && m.FunctionalId == j.FunctionId ||
m.Careerlevel != null && m.Careerlevel == j.CarrerLevelId ||
m.SalId != null && m.SalId == j.SalaryRangeId)
join ur in entities.UserRegistrations on j.UserId equals ur.UserId
join r in entities.EmplrRegistrations on j.UserId equals r.JobSeekerID
where m.Status == true && m.UserId == 1
select new { r.CompanyLogo, j.JobName, j.JobId, ur.UserId, r.JobSeekerID
, ur.FirstName, j.JobType, j.JobCareerLevel, j.JobLocation };
var list = query.Distinct().ToList();

linq to sql make simple group by at the end

I have this linq
(from a in Customers
join b in CustomerContacts.Where(p => p.Contact.ContactType.Code == "phone") on a.Id equals b.CustomerId into bb
from b in bb.DefaultIfEmpty()
join e in CustomerContacts.Where(p => p.Contact.ContactType.Code == "email") on a.Id equals e.CustomerId into ee
from e in ee.DefaultIfEmpty()
join f in Bookings.Where(p => p.EntityId == 4) on a.Id equals f.CustomerId into ff
from f in ff.DefaultIfEmpty()
join h in CustomerAddresses on a.Id equals h.CustomerId into hh
from h in hh.DefaultIfEmpty()
where
(b.Contact.Value.Contains("123") || e.Contact.Value.Contains("123"))
&& (a.EntityId == 4 || f != null)
select new {
a.Id,
phone = b.Contact.Value,
email = e.Contact.Value,
count = Vehicles.Where(p => p.CustomerId == a.Id).Count(),
h.Address.State,
h.Address.Suburb
}
)
It translated to sql (mysql)
SELECT `a`.`Id`, `b.Contact`.`Value` AS `phone`, `e.Contact`.`Value` AS `email`, (
SELECT COUNT(*)
FROM `Vehicle` AS `p2`
WHERE `p2`.`CustomerId` = `a`.`Id`
) AS `count`, `h.Address`.`State`, `h.Address`.`Suburb`
FROM `Customer` AS `a`
LEFT JOIN (
SELECT `p`.*
FROM `CustomerContact` AS `p`
INNER JOIN `Contact` AS `p.Contact` ON `p`.`ContactId` = `p.Contact`.`Id`
INNER JOIN `ContactType` AS `p.Contact.ContactType` ON `p.Contact`.`ContactTypeId` = `p.Contact.ContactType`.`Id`
WHERE `p.Contact.ContactType`.`Code` = 'phone'
) AS `t` ON `a`.`Id` = `t`.`CustomerId`
LEFT JOIN `Contact` AS `b.Contact` ON `t`.`ContactId` = `b.Contact`.`Id`
LEFT JOIN (
SELECT `p0`.*
FROM `CustomerContact` AS `p0`
INNER JOIN `Contact` AS `p.Contact0` ON `p0`.`ContactId` = `p.Contact0`.`Id`
INNER JOIN `ContactType` AS `p.Contact.ContactType0` ON `p.Contact0`.`ContactTypeId` = `p.Contact.ContactType0`.`Id`
WHERE `p.Contact.ContactType0`.`Code` = 'email'
) AS `t0` ON `a`.`Id` = `t0`.`CustomerId`
LEFT JOIN `Contact` AS `e.Contact` ON `t0`.`ContactId` = `e.Contact`.`Id`
LEFT JOIN (
SELECT `p1`.*
FROM `Booking` AS `p1`
WHERE `p1`.`EntityId` = 4
) AS `t1` ON `a`.`Id` = `t1`.`CustomerId`
LEFT JOIN `CustomerAddress` AS `h` ON `a`.`Id` = `h`.`CustomerId`
LEFT JOIN `Address` AS `h.Address` ON `h`.`AddressId` = `h.Address`.`Id`
WHERE ((LOCATE('123', `b.Contact`.`Value`) > 0) OR (LOCATE('123', `e.Contact`.`Value`) > 0)) AND ((`a`.`EntityId` = 4) OR `t1`.`Id` IS NOT NULL)
and the result
however it contains duplicated Id, I want to add group by a.Id at the end to remove duplicated Id. Tried with group by but it cannot achieve some thing like this
SELECT `a`.`Id`, `b.Contact`.`Value` AS `phone`, `e.Contact`.`Value` AS `email`, (
SELECT COUNT(*)
FROM `Vehicle` AS `p2`
WHERE `p2`.`CustomerId` = `a`.`Id`
) AS `count`, `h.Address`.`State`, `h.Address`.`Suburb`
FROM `Customer` AS `a`
LEFT JOIN (
SELECT `p`.*
FROM `CustomerContact` AS `p`
INNER JOIN `Contact` AS `p.Contact` ON `p`.`ContactId` = `p.Contact`.`Id`
INNER JOIN `ContactType` AS `p.Contact.ContactType` ON `p.Contact`.`ContactTypeId` = `p.Contact.ContactType`.`Id`
WHERE `p.Contact.ContactType`.`Code` = 'phone'
) AS `t` ON `a`.`Id` = `t`.`CustomerId`
LEFT JOIN `Contact` AS `b.Contact` ON `t`.`ContactId` = `b.Contact`.`Id`
LEFT JOIN (
SELECT `p0`.*
FROM `CustomerContact` AS `p0`
INNER JOIN `Contact` AS `p.Contact0` ON `p0`.`ContactId` = `p.Contact0`.`Id`
INNER JOIN `ContactType` AS `p.Contact.ContactType0` ON `p.Contact0`.`ContactTypeId` = `p.Contact.ContactType0`.`Id`
WHERE `p.Contact.ContactType0`.`Code` = 'email'
) AS `t0` ON `a`.`Id` = `t0`.`CustomerId`
LEFT JOIN `Contact` AS `e.Contact` ON `t0`.`ContactId` = `e.Contact`.`Id`
LEFT JOIN (
SELECT `p1`.*
FROM `Booking` AS `p1`
WHERE `p1`.`EntityId` = 4
) AS `t1` ON `a`.`Id` = `t1`.`CustomerId`
LEFT JOIN `CustomerAddress` AS `h` ON `a`.`Id` = `h`.`CustomerId`
LEFT JOIN `Address` AS `h.Address` ON `h`.`AddressId` = `h.Address`.`Id`
WHERE ((LOCATE('123', `b.Contact`.`Value`) > 0) OR (LOCATE('123', `e.Contact`.`Value`) > 0)) AND ((`a`.`EntityId` = 4) OR `t1`.`Id` IS NOT NULL)
Group by `a`.`Id`
Have you tried something like this?
(from a in Customers
join b in CustomerContacts.Where(p => p.Contact.ContactType.Code == "phone") on a.Id equals b.CustomerId into bb
from b in bb.DefaultIfEmpty()
join e in CustomerContacts.Where(p => p.Contact.ContactType.Code == "email") on a.Id equals e.CustomerId into ee
from e in ee.DefaultIfEmpty()
join f in Bookings.Where(p => p.EntityId == 4) on a.Id equals f.CustomerId into ff
from f in ff.DefaultIfEmpty()
join h in CustomerAddresses on a.Id equals h.CustomerId into hh
from h in hh.DefaultIfEmpty()
where
(b.Contact.Value.Contains("123") || e.Contact.Value.Contains("123"))
&& (a.EntityId == 4 || f != null)
select new {
a.Id,
phone = b.Contact.Value,
email = e.Contact.Value,
count = Vehicles.Where(p => p.CustomerId == a.Id).Count(),
h.Address.State,
h.Address.Suburb
}).GroupBy(i => i.Id).ToList();

Left Join only return values where UserID match

Left join return duplicate products when 1 or more user save same product.
I solved the problem in SQL query.here's a query:
select p.ProductID,
(case when c.UserID = 3 then 'true' else 'false' end) as flag
from product as p
left join SavedItem as c on product.ProductID = c.ProductID and
c.UserID = 3
can't figure out how to do in a Entity framework.
left join SavedItem as c on product.ProductID = c.ProductID and
c.UserID = 3
Left join can be solve like this:
join c in SavedItem on p.ProductID equals c.ProductID into lj
from c in lj.DefaultIfEmpty()
c.UserID = 3 where to place this?
Try this:
var query= from product in context.Products
from SavedItem in context.SavedItems.Where(c=> c.ProductID = product.ProductID && c.UserID == 3).DefaultIfEmpty()
select new {
ProductID=product.ProductID,
Flag=(SavedItem==null || SavedItem.UserID != 3) ? false : true
};
Here! I found the solution.
from product in context.Products
join c in context.SavedItems
on new { p1 = (int?)product.ProductID , p2 = (int?)cat.UserID }
equals new { p1 = c.ProductID ,p2 = c.UserID} into lj
from c in lj.DefaultIfEmpty()
select new{
...
flag = (c.UserID == cat.UserID ? "true" : "false"),
...
}

What's wrong with this LINQ?

I am using LINQ TO Entities & need to use Union operator.
This is my raw sql query.
(select DISTINCT c.DocumentId from [sDocument].[tDocumentStatus] c
inner join [sDocument].[tTOCStructure] d on c.DocumentId = d.FolderID
inner join [sDocument].[tAudit] e on c.DocumentId = e.FolderID
where d.FolderType = 2 and d.isDeleted = 0 and d.ClientID = 9 and e.AuditDescriptionID != 10)
Union
(select DISTINCT c.FolderID from [sDocument].[tTOCStructure] c
inner join [sDocument].[tAudit] e on c.DocumentId = e.FolderID
where c.FolderType = 2 and c.isDeleted = 0 and c.ClientID = 9 )
When I run the above sql, I get around 45 records. That's right as well
Below is LINQ for the same requirement.
IQueryable<DocumentListMapper> query = (
from c in entities.tDocumentStatus
join d in entities.tTOCStructures on c.DocumentId equals d.FolderID
join e in entities.tAudits on c.DocumentId equals e.FolderID
where d.FolderType == 2 && d.isDeleted == false && d.ClientID == clientId && e.AuditDescriptionID != 10
select new DocumentListMapper()
{
DocumentId = c.DocumentId,
DocumentName = d.CheckoutFolderName,
PublishDate = c.AssignedDate
}).Distinct().Union(
from c in entities.tTOCStructures
join e in entities.tAudits on c.FolderID equals e.FolderID
where c.FolderType == 2 && c.isDeleted == false && c.ClientID == clientId
select new DocumentListMapper()
{
DocumentId = c.FolderID,
DocumentName = c.CheckoutFolderName,
PublishDate = e.TaskDateTime
}).Distinct().OrderBy(x => x.PublishDate).Skip(pager * 50).Take(50);
But this LINQ returns more than 2500 records. This is not the desired records.
What's wrong in my LINQ??

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