Is there a way to accurately convert the following SQL query to LINQ
SELECT * FROM T1
WHERE ColumnA IN (
SELECT FkColumnA FROM T2
WHERE FkColumnB IN (
SELECT ColumnB FROM T3
WHERE FkColumnC IN (
SELECT ColumnC FROM T4
WHERE FkColumnD = 1)) AND FkColumnE is null AND ColumnF = 0)
Also, does anyone know of any documentation wherein any logic or guideline to convert SQL queries to LINQ is laid out?
EDIT 1:
The equivalent for the above using JOINS would be as below:
select * from T1 a
inner join T2 b on a.FKColumnA = b.ColumnA
inner join T3 c on c.ColumnB = b.FkColumnB
inner join T4 d on d.ColumnC = c.FkColumnC
where a.FkColumnD is null and a.ColumnE = 0
and d.ColumnC = 1
and it's equivalent LINQ query would be
var linq = from q in context.T1
join r in context.T2
on q.FKColumnA equals r.ColumnA
join s in context.T3
on r.FkColumnB equals s.ColumnB
join t in context.T4
on s.FkColumnC equals t.ColumnC
where q.FkColumnD != null && q.ColumnE == false && t.ColumnC == 56816
select q.FkColumnF;
But using JOINS looked to be a bit more simpler and better in LINQ. Thus the question is for my knowledge purpose only.
Translating your query literally, we get the following LINQ statement:
var results = table1.Where(t1 => table2.Where(
t2 =>
table3.Where(
t3 =>
table4.Where(t4 => t4.FkColumnD == 1)
.Select(t4 => t4.ColumnC)
.Contains(t3.FkColumnC))
.Select(t3 => t3.ColumnB)
.Contains(t2.FkColumnB) && !t2.FkColumnE.HasValue && t2.ColumnF == 0)
.Select(t2 => t2.FkColumnA)
.Contains(t1.ColumnA));
This results in an IEnumerable<T1> which you can use as required.
As far as I know there is no "documentation" on converting syntax, this, as a developer, is your job. However, I personally find LINQPad very useful when constructing LINQ statements.
Related
I want to do a JOIN with LINQ using an OR statement.
Here is the SQL query I'm starting with:
SELECT t.id
FROM Teams t
INNER JOIN Games g
ON (g.homeTeamId = t.id OR g.awayTeamId = t.id)
AND g.winningTeamId != 0
AND g.year = #year
GROUP BY t.id
I'm having trouble converting that ON clause to LINQ. This is where I'm at:
var y = from t in db.Teams
join g in db.Games on t.ID equals g.AwayTeamID //missing HomeTeamID join
where g.WinningTeamID != 0
&& g.Year == year
group t by t.ID into grouping
select grouping;
I think I could use:
join g in db.Games on 1 equals 1
where (t.ID == g.HomeTeamID || t.ID == g.AwayTeamID)
and this works but seems kind of seems hacky. Is there a better way?
I struggled with this as well until I found the following solution, which worked well for my situation:
var y = from t in db.Teams
from g in db.Games
where
(
t.ID == g.AwayTeamID
|| t.ID == g.HomeTeamID
)
&& g.WinningTeamID != 0
&& g.Year == year
group t by t.ID into grouping
select grouping;
Under the covers, your solution probably works very close to this one. However, I bet this one is just a bit faster if you benchmark it since it is not JOINING every item in the first dataset with every item in the second dataset, which could be a disaster if either (or both) dataset were really big.
The where clause applies a boolean condition, so using "||" is the way to go. You can chain multiple where clauses but I believe that will give you a "and" operation, rather than an "or".
I think you can do like this:
from t1 in db.Table1
// inner join with OR condition
from t2 in db.Table2 where t1.col1 == t2.col1 || t1.col2 == t2.col2
// normal inner join
join t3 in db.Table3 on t1.col1 equals t3.col1
// inner join with complex condition
join t4 in db.Table4 on t2.col4 equals t4.col4 where t2.col5.Contains(t4.col5)
// left join with OR condition
from t5 in db.Table5.Where(x => x.col5 == t1.col5 || x.col6 == t1.col6).DefaultIfEmpty()
select new {
x = 1 // select whatever you want here
}
The underlying SQL query probably won't use native sql joins but the above is just a way to make your code look pretty and organized.
I would like to write the following SQL query with LINQ syntax to understand the fundamentals of LINQ queries.
SELECT q.*, qpph.*
FROM [Questions] AS q
LEFT OUTER JOIN [QuestionPoolPickHandles] AS qpph
ON qpph.QuestionId = q.Id AND qpph.PickerId = 100
WHERE qpph.Id IS NULL;
How can I apply left outer join and a condition in its ON clause at the same time using LINQ syntax? From my readings, it seems it is likely to be not possible.
Here's what I've tried so far.
var result = from q in context.Questions
join qpph in context.PoolPickHandles
on q.Id equals qpph.PickerId into Handles // notice the 'qpph.PickerId = 100' is absent
from m in Handles.DefaultIfEmpty()
where m == null
select q;
Any further elaboration will be appreciated.
With the help of the comments on the question, I've figured out writing the query using LINQ syntax.
from q in context.Questions
join qpph in context.PoolPickHandles
on new { questionId = q.Id, pickerId = user.Id }
equals new { questionId = qpph.QuestionId, pickerId = qpph.PickerId }
into Handles
from m in Handles.DefaultIfEmpty()
where m == null
select q;
Anyone can help me how to convert sql statement to linq and lambda like this ?
SELECT
tbl_terms.ID,
tbl_terms.Terms
FROM
tbl_terms
LEFT JOIN tbl_asn_uploaddoc ON tbl_terms.ID != tbl_asn_uploaddoc.Id_term
WHERE
tbl_asn_uploaddoc.Nip = '201948274838491943' && tbl_asn_uploaddoc.STATUS = 1
Thanks in advance
LINQ is mostly similar to SQL if you use query syntax instead of method syntax. Here is what I could gather quickly. Can't test because I don't have your model classes.
var Result = from t in context.tbl_terms
join d in context.tbl_asn_uploaddoc on t.ID != d.Id_term
where d.Nip = '201948274838491943' && d.STATUS = 1
select t.ID, t.Terms
Use below query that will give you LEFT JOIN on both of your entity,
var result = (from t in _con.tbl_Terms
join u in _con.tbl_asn_uploaddocs on t.ID equals u.Id_term
into tu
where !tu.Any()
from u in tu.DefaultIfEmpty()
where u.Nip == "201948274838491943" && u.STATUS == 1
select new
{
ID = t.ID,
Terms = t.Terms
}).ToList();
Where _con is your context.
You can use SQL to LINQ converter tool Linqer
Linqer is a SQL to LINQ conversion tool. It helps learning LINQ and convert existing SQL statements.
I have the following TSQL
SELECT COUNT(M.MuseumID) as [ACTIVECARDHOLDERS]
FROM Museum AS M
WHERE M.MuseumID IN
(SELECT MAX(X.MuseumID) AS MuseumID
FROM (SELECT BioStation.[MuseumID]
,BioStation.[PersonID]
,ISNULL(M.ISCARDINVALIDATED,0) AS [ISCARDINVALIDATED]
FROM Museum AS M
INNER JOIN BioStation ON BioStation.MuseumID = Museum.MuseumID
WHERE M.CASESTATE=7 AND M.CASESTATUS=6) AS X
GROUP BY X.PERSONID)
AND ISNULL(M.ISCARDINVALIDATED,0)=0;
I'm trying to convert to linq in C#, starting with the inner most query, however I'm unsure how to nest them in linq with group\max. This is what I have so far that's bug free:
var query = (from m in dbContext.Museum
join b in dbContext.BioStation on m.MuseumID equals b.MuseumID
where m.CaseState == 7 && m.CaseStatus == 6
select new {b.MuseumID, b.PersonID, IsCardInvalidated = (m.IsCardInvalidated == null ? false : m.IsCardInvalidated) }).AsQueryable();
Any help with the translation would be appreciated, thanks.
I need to convert this query:
SELECT *
FROM Table1 AS t1
left join Table2 t2
on t1.Column1 = t2.Column1
left join Table2 t2
on t1.Column2 = t2.Column2 and t2.Column3 = 1
to LinqToSQL and Lambda.
I have been looking for a good interpretation of the SQL joins in LINQ but haven't had much luck in finding anything that clearly states how to take advantage of LINQ to achieve the different joins offered in SQL.
Can someone offer an explanation of how the different SQL joins can be taken advantage of in SQL.
Try something like this:
AlternativeLearningPlanYears
.GroupJoin
(
Leas,
x => x.DistrictLeaId,
y => y.LeaId,
(x,y) => new {x,y}
)
.GroupJoin
(
Leas,
x => new {x.PrivateInstitutionId,1},
y => new {y.PrivateInstitutionId,IsPrivateInstitution},
(x,y) => new {x,y}
)
.Where
(
z => z.x.SchoolYear == 23
&& z.x.Granted == 1
&& z.x.PrivateInstitutionId == null
&& z.x.DistrictName == null
)
I don't have your schema so there may be some errors, so post them and we'll work them out..