Linq 2 SQL Syntax Help - sql

I am almost done converting a MySQL app to Linq2SQL but struggling to get my head round this last SQL query
SELECT a.URL, b.URL AS DuplicateURL
FROM Pages a
INNER JOIN Pages b ON a.MetaDescription = b.MetaDescription
AND a.PageID <> b.PageID
WHERE a.DomainID = #reportid
AND b.DomainID = #reportid
AND LENGTH(TRIM(a.MetaDescription)) > 0
AND a.URL < b.URL
ORDER BY a.URL ASC
Could anymore give me some syntax help on how I would create this query in Linq2SQL?
Any help greatly appreciated

It goes like this:
var DuplicatePages =
from a in DBContext.Pages
join b in DBContext.Pages on a.MetaDescription equals b.MetaDescription
where (a.PageID <> b.PageID) && (a.DomainID == ReportID) &&
(b.DomainID == ReportID) && (a.MetaDescription.Trim().Length > 0) &&
(a.URL < b.URL)
orderby a.URL
select new { Url = a.URL, DuplicateUrl = b.URL };

That's pretty straigtforward:
var reportId = ...;
var duplicates =
from a in db.Pages
from b in db.Pages
where a.MetaDescription == b.MetaDescription
where a.PageID != b.PageID
where a.DomainID == reportId
where b.DomainID == reportId
where a.MetaDescription.Trim().Length > 0
where a.URL < b.URL
orderby a.URL
select new { Url = a.URL, DuplicateUrl = b.Url }

Related

hat is the LINQ equivalent for the following SQL query?

T-SQL query:
SELECT T1.ID,
T1.UserId,
T1.ServerId,
T1.DiskId,
T1.Date_ PreviousDate_,
T1.Row,
MIN(T2.Date_) AS Date_,
DATEDIFF(MINUTE, T1.Date_, MIN(T2.Date_)) AS MinutesDiff
FROM IesLogs T1
LEFT JOIN IesLogs T2
ON T1.DiskId = T2.DiskId
where T1.DiskId = 2 AND T2.Date_ > T1.Date_ AND T1.Row = T2.Row
GROUP BY T1.ID,T1.UserId, T1.ServerId, T1.DiskId, T1.Date_, T1.[Row]
ORDER BY T1.DiskId, T1.[Row], T1.Id
I am getting more data than I expected.
var result = (
from i in context.IesLogs
join i2 in context.IesLogs
on i.DiskId equals diskId into i2left
from i3 in i2left.DefaultIfEmpty()
where
i.UserId == userId
&& i3.Date > i.Date
&& i.Row == i3.Row
group i3 by new {i.Id, i.ServerId,i.DiskId, i.Row, PreviousDate = i.Date, i3.Date} into logs
orderby logs.Key.DiskId, logs.Key.Row,logs.Key.Id ascending
select new IesLogStatisticsDto
{
Id = logs.Key.Id,
ServerId = logs.Key.ServerId,
DiskId = logs.Key.DiskId,
PreviousDate = logs.Key.PreviousDate,
Date = logs.Min(x => x.Date),
Row = logs.Key.Row,
DateDiff = Convert.ToInt32((logs.Min(x => x.Date) - logs.Key.PreviousDate).TotalMinutes)
}).ToList();
I'm getting 12 when I should be getting 6 data. How Can I solve this ?
I think the reason why I'm getting a lot of data is the(i3.Date > i.Date) in the code blog above but I have to implement this line.
Your LINQ query has wrong grouping. You have to remove i3.Date from grouping key.
A little bit refactored:
var query =
from i in context.IesLogs
join i2 in context.IesLogs
on i.DiskId equals diskId into i2left
from i2 in i2left.DefaultIfEmpty()
where
i.UserId == userId
&& i2.Date > i.Date
&& i.Row == i2.Row
group i2 by new {i.Id, i.ServerId, i.DiskId, i.Row, PreviousDate = i.Date} into logs
orderby logs.Key.DiskId, logs.Key.Row, logs.Key.Id ascending
select new IesLogStatisticsDto
{
Id = logs.Key.Id,
ServerId = logs.Key.ServerId,
DiskId = logs.Key.DiskId,
PreviousDate = logs.Key.PreviousDate,
Date = logs.Min(x => x.Date),
Row = logs.Key.Row,
DateDiff = Convert.ToInt32((logs.Min(x => x.Date) - logs.Key.PreviousDate).TotalMinutes)
};

Database query - unusual query

I'm trying to transfer a query to LINQ
It's a bit complicated and I don't know if I'm doing the right thing
There is also a problem with SELECT to save it properly
SQL QUERY:
SELECT ISNULL(SUM(1),0) TotalSubmitted,
ISNULL(SUM(CASE WHEN Pic.PhotoFileName IS NULL THEN 0 ELSE 1 END),0) TotalAssigned
FROM tblFromPhone Ph
INNER JOIN tblOfficer O ON Ph.OfficerCode = O.Code
OUTER APPLY(SELECT PhotoFileName FROM tblPhotos P
WHERE P.validityTo IS NULL
AND P.PhotoFileName = Ph.DocName
AND P.OfficerID = O.OfficerID)Pic
WHERE CAST(Ph.LandedDate AS DATE) BETWEEN #FromDate AND #ToDate
AND O.ValidityTo IS NULL
AND DocType = N'E'
AND OfficerCode = #OfficerCode
My LINQ:
var res = (from FP in context.TblFromPhone
join O in context.TblOfficer on FP.OfficerCode equals O.Code
join P in context.TblPhotos on FP.DocName equals P.PhotoFileName into P
from Ph in P.Where(x => x.OfficerId == O.OfficerId).DefaultIfEmpty()
where Ph.ValidityTo == null
where FP.LandedDate >= DateTime.Parse(fromDate)
&& FP.LandedDate <= DateTime.Parse(toDate)
&& O.ValidityTo == null
&& FP.DocType == "E"
&& FP.OfficerCode == officerCode
select new EnrolmentModel()
{
TotalSubmitted = // How to make?
TotalAssigned = // How to make?
})
.FirstOrDefault();

SQL to Entity Framework query for distinct instances

I need to translate the following query from SQL into an Entity Framework query. Can anyone please help.
var query3 = string.Format(#"
SELECT DISTINCT
Boxes.BoxName,
Employees.EmployeeNumber,
Boxes.Port,
Boxes.SerialNumber
FROM
Eventlog
INNER JOIN Boxes
ON Eventlog.SerialNumber = Boxes.SerialNumber
INNER JOIN Employees
ON Eventlog.EmployeeId = Employees.EmployeeId
WHERE
ActionId = {4}
AND Boxes.Deactivated = 0
AND ( ('*' = '{0}')
OR (Boxes.SerialNumber = '{0}') )
AND ( (-1 = {1})
OR (Employees.EmployeeId = '{1}') )
AND EventTime >= '{2}'
AND EventTime <= '{3}'
", boxFilter3, ReportEmployeeIdFilter, ReportStartDate, ReportEndDate, actionFilter);
Something like this should work:
var query = (from log in context.Eventlog
join box in context.Boxes
on log.SerialNumber equals box.SerialNumber
join employee in context.Employees
on log.EmployeeId equals employee.EmployeeId
where log.ActionId == actionFilter
&& box.Deactivated == 0
&& (boxFilter3 == "*" || box.SerialNumber == boxFilter3)
&& (ReportEmployeeIdFilter == -1 || employee.EmployeeId == ReportEmployeeIdFilter)
&& log.EventTime >= ReportStartDate
&& log.EventTime <= ReportEndDate
select new
{
box.BoxName,
employee.EmployeeNumber,
box.Port,
box.SerialNumber
})
.Distinct();

LINQ - Left Outer Join with multiple parameters in Where clause

How can I do this SQL query in LINQ:
select * from chat c
left outer join lead s on c.key = s.id
where (typeId = 5 AND c.key = #clientId) OR (c.typeId = 4 AND s.clientId = #clientId)
Or this SQL query -- Same, same
select * from chat c
where (typeId = 5 AND c.key = #clientId) OR (typeId = 4 AND c.key in (select id from lead where clientId = #clientId))
What I have:
var chatter = (from chat in linq.Chat
join lead in linq.Lead
on chat.key equals lead.Id.ToString() into clientLeads
from cl in clientLeads.Where(l => l.clientId == clientId).DefaultIfEmpty()
where (chat.typeId == 5 && chat.key == clientId.ToString()) ||
(chat.typeId == 4 && chat.key == cl.Id.ToString())
select chat).WithPath(prefetchPath).OrderByDescending(c => c.CreatedDate);
The above LINQ query doesn't yeild any results from the latter WHERE clause, what am I missing?
I translated the second query to linq:
var leadIds = linq.Lead.Where(l => l.clientId == clientId.ToString()).Select(l => l.id);
var chatter = from chat in linq.Chat
where (chat.typeId == 5 && chat.key == clientId.ToString()) ||
(chat.typeId == 4 && leadIds.Contains(chat.key));

Linq to SQL query taking forever

Ok, first I thought I had a problem with how I was querying things. But apparently the problem lies in how linq translates my query to sql.
Here's my linq:
var items = (from p in ctx.bam_Prestatie_AllInstances
join q in ctx.bam_Zending_AllRelationships on p.ActivityID equals q.ReferenceData
join r in ctx.bam_Zending_AllInstances on q.ActivityID equals r.ActivityID
orderby p.LastModified descending
where r.PrestatieOntvangen >= vanaf && r.PrestatieOntvangen <= tm
select new Data.BAMPrestatieInstance
{
Aanvaard = p.PrestatieAanvaard,
Contactnummer = r.ContactNr,
Identificatie = p.Identificatie,
Foutmelding = ((p.Foutmelding == "" || p.Foutmelding == null) && p.PrestatieAanvaard == null) ? "De prestatie is bezig met verwerkt te worden." : p.Foutmelding.Replace("\r\n", " "),
Ontvangen = p.PrestatieZendingOntvangen,
Uitvoerdatum = p.Uitvoerdatum.Replace('-', '/'),
Zender = r.Zender,
PrestatieCode = p.PrestatieCode,
ZendingsNr = r.Zendingnummer.ToString(),
GroepsAanvaarding = r.Identificatie
}).Take(100);
Which gets translated in:
SELECT TOP (100) [t3].[Zender], [t3].[ContactNr] AS [Contactnummer], [t3].[Identificatie], [t3].[value] AS [Uitvoerdatum], [t3].[PrestatieZendingOntvangen] AS [Ontvangen], [t3].[PrestatieAanvaard] AS [Aanvaard], [t3].[value2] AS [Foutmelding], [t3].[PrestatieCode], [t3].[value3] AS [ZendingsNr], [t3].[Identificatie2] AS [GroepsAanvaarding]
FROM (
SELECT [t2].[Zender], [t2].[ContactNr], [t0].[Identificatie], REPLACE([t0].[Uitvoerdatum], #p0, #p1) AS [value], [t0].[PrestatieZendingOntvangen], [t0].[PrestatieAanvaard],
(CASE
WHEN (([t0].[Foutmelding] = #p2) OR ([t0].[Foutmelding] IS NULL)) AND ([t0].[PrestatieAanvaard] IS NULL) THEN CONVERT(NVarChar(3800),#p3)
ELSE REPLACE([t0].[Foutmelding], #p4, #p5)
END) AS [value2], [t0].[PrestatieCode], CONVERT(NVarChar,[t2].[Zendingnummer]) AS [value3], [t2].[Identificatie] AS [Identificatie2], [t2].[PrestatieOntvangen], [t0].[LastModified]
FROM [dbo].[bam_Prestatie_AllInstances] AS [t0]
INNER JOIN [dbo].[bam_Zending_AllRelationships] AS [t1] ON [t0].[ActivityID] = [t1].[ReferenceData]
INNER JOIN [dbo].[bam_Zending_AllInstances] AS [t2] ON [t1].[ActivityID] = [t2].[ActivityID]
) AS [t3]
WHERE ([t3].[PrestatieOntvangen] >= #p6) AND ([t3].[PrestatieOntvangen] <= #p7)
ORDER BY [t3].[LastModified] DESC
As you can see, first it selects EVERYTHING and then it takes the top 100 and does the where. Why is this? Why can't it directly do the top 100, I think the problem why my queries run so long is because of this. Is there a better way to construct my linq query then?
Thanks
Try this:
var items = from p in ctx.bam_Prestatie_AllInstances.OrderByDesc(p => p.LastModified).Take(100)
join q in ctx.bam_Zending_AllRelationships on p.ActivityID equals q.ReferenceData
join r in ctx.bam_Zending_AllInstances on q.ActivityID equals r.ActivityID
where r.PrestatieOntvangen >= vanaf && r.PrestatieOntvangen <= tm
select new Data.BAMPrestatieInstance
{
Aanvaard = p.PrestatieAanvaard,
Contactnummer = r.ContactNr,
Identificatie = p.Identificatie,
Foutmelding = ((p.Foutmelding == "" || p.Foutmelding == null) && p.PrestatieAanvaard == null) ? "De prestatie is bezig met verwerkt te worden." : p.Foutmelding.Replace("\r\n", " "),
Ontvangen = p.PrestatieZendingOntvangen,
Uitvoerdatum = p.Uitvoerdatum.Replace('-', '/'),
Zender = r.Zender,
PrestatieCode = p.PrestatieCode,
ZendingsNr = r.Zendingnummer.ToString(),
GroepsAanvaarding = r.Identificatie
};
Since the sort applies only to your first table, I'd try to force the order by and take 100 to be applied before the join.