I want to rewrite this simple MS SQL Query in Linq To SQL:
SELECT * FROM Table1 T1
LEFT JOIN Table2 T2 ON T1.ID = T2.Table1ID OR T1.FirstName = T2.FirstName
How do I rewrite this in Linq To SQL?
Try this, although I don't know how well Linq-to-SQL will translate it:
from t1 in ctx.Table1
from t2 in ctx.Table2
.Where(t => t1.ID == t.Table1ID ||
t1.FirstName == t.Firstname)
.DefaultIfEmpty()
select new {t1, t2}
I don't believe this can be done because I don't think you can do the OR part of the join. The way you do joins in L2S would be (roughly)
join .. on
new {
T1.ID,
T1.FirstName
} equals new {
T2.Table1ID,
T2.FirstName
}
but that would match both.
Only thing I can think you could do would be to do some sort of subquery in there. But that's probably not what you're looking for. Sklivvz's suggestion may be the best one.
This is an inner join.
from t1 in ctx.Table1
from t2 in ctx.Table2
where t1.ID == t2.Table1ID ||
t1.FirstName == t2.Firstname
select t1
To get a left join it looks like you use DefaultIfEmpty(), per MSDN.
from t1 in ctx.Table1
from t2 in ctx.Table2.DefaultIfEmpty()
where t1.ID == t2.Table1ID ||
t1.FirstName == t2.Firstname
select t1
Related
I can I generate the below SQL query select using entity framework core 3.1.8 ?
SELECT *
FROM table1 t1
LEFT JOIN table2 t2 ON t1.Id = t2.table1Id AND t2.Status IN (1,2,3)
I tried the code below
var statuses = new List<int> { 1, 2, 3 };
var result = await (from t1 in _context.Table1
join t2 in _context.Table2
on t1.Id equals t2.TableId
into results
from m in results.Where(x => statuses.Contains((int)x.Status)).DefaultIfEmpty()
select new ResultDto
{
}).ToListAsync();
But the query generates a suquery
UPDATED
The query suggested by
#Svyatoslav Danyliv generated the SQL below
SELECT [a].[Id], [a].[ActionWith], [a].[CreatedBy], [a].[DateCreated], [t].[table1Id], [t].[Comment], [t].[CreatedBy], [t].[DateCreated]
FROM [Table1] AS [a]
LEFT JOIN (
SELECT [c].[Id], [c].[table1Id], [c].[Comment], [c].[CreatedBy], [c].[DateCreated]
FROM [Table2] AS [c]
WHERE [c].[Status] IN (1, 2)
) AS [t] ON [a].[Id] = [t].[table1Id]
As documented in Collection selector references outer in a where clause, you can rewrite your query in the following way:
var query =
from t1 in _context.Table1
from t2 in _context.Table2
.Where(t1 => t1.Id == t2.TableId && statuses.Contains((int)x.Status))
.DefaultIfEmpty()
select new ResultDto
{
}
Note that GroupJoin has limited translation in EF Core, only simple LEFT JOIN.
I need to join 5 tables in a query. 3 of these tables must have relations, but two of them are optionally connected to an entry.
Because of this, I am trying to do a LEFT JOIN to Table4 and Table5 like this:
var cDesc = (cDesc == null ? "" : cDesc);
var cStreet = (cStreet == null ? "" : cStreet);
var q = await (from t1 in MyContext.Table1
join t2 in MyContext.Table2
on t1.ID equals t2.ObjectID
join t3 in MyContext.Table3
on t2.TeamID equals t3.TeamID
join t4 in MyContext.Table4
on t1.ID equals t4.ObjectID
into join3
from j3 in join3.DefaultIfEmpty()
join t5 in MyContext.Table5
on j3.StorageID equals t5.StorageID
where t2.ObjectType.Equals(16)
&& t3.UserID.Equals(userID)
&& t1.Description.Contains(cDesc)
&& l.Address.Contains(cStreet)
orderby t1.ID descending
select new Table1ListModel
{
ID = t1.ID,
Description = t1.Description,
Address = t5.Address
}
)
.Take(takeThis)
.ToListAsync();
But this query only works for rows that has a connection to Table4, so I'm doing something wrong obviously.
Am I doing the join correctly? Or is the problem that I want to run a where on address that comes from the fifth table?
Basically once you left join one table into a query any additional tables that you want to join to that one should almost always also be done with left joins. In your case you're saying you want keep rows in Table1 that don't have a match in Table4, but then you say you only want matches between Table4 and Table5 which basically will remove all the Table1 results that didn't have a match in Table4. Basically you want something like this
from j3 in join3.DefaultIfEmpty()
join temp5 in MyContext.Table5
on j3.StorageID equals temp5.StorageID into join4
from t5 in join4.DefaultIfEmpty()
This looks like a source of your problem:
join t4 in MyContext.Table4
on t1.ID equals t4.ObjectID
into join3
This means that you are inner joining Table4 to Table1
How to convert the below SQL query into LINQ query for C#.net
Select t1.id,t2.Name
From table1 t1
INNER JOIN table t2
ON ((t1.column3 is null and t1.id = t2.id)
OR( t.Column3 is NOT NULL and t1.column3 = t3.Column3))
Join tblXYZ xyz on t1.column4 = xys.columnn2
I was unable to add or condition after first set up comparison in linq query, please suggest correct way to achieve this in linq.
Making some assumptions about what you meant, I would suggest hoisting the OR to a union:
(from t1 in table1
join t2 in table2 on t1.Column3 equals t2.Column3
join xyz in tblXYZ on t1.Column4 equals xyz.column2
where t1.Column3 != null).Union(
from t1 in table1
join t2 in table2 on t1.id == t2.id
join xyz in tblXYZ on t1.Column4 equals xyz.column2
where t1.Column3 == null)
I am trying to write a linq query that resembles this SQL:
SELECT * FROM Table1
WHERE EXISTS (
SELECT 1 FROM Table2
WHERE Table1.ColA = Table2.ColA
AND Table1.ColB = Table2.ColB
)
Except Table2 is an object list I already have previously from the database.
I know how to use contains() to emulate an SQL "IN SUBQUERY" using a object list outside of the database when one column is involved:
var query = from t1 in db.Table1
where MyObjList.Select(o => o.Field1).Contains(t1.Col1)
select t1;
I figure I can do a join in Linq. But will that perform ok? I hope avoid a database call per object in my list.
var q = from t1 in db.Table1
from t2 in db.Table2.Where(x => x.ColA == t1.ColA && x.ColB == t1.ColB)
select t1;
Try like this:
var query = from t1 in db.Table1
join t2 in db.Table2 on t1.ColA equals t2.ColA
Where t1.ColB == t2.ColB
Select t1;
OR without Join
var query = from t1 in db.Table1
from t2 in db.Table2
Where t1.ColA == t2.ColA && t1.ColB == t2.ColB
Select t1;
How can I make a Linq To SQL join on multiple tables where 1 table should produce a Cartesian product.
To shed some more light, here is a sample of the SQL query.
SELECT Table1.MyField, Setup.SomeField
FROM Table1 INNER JOIN Table2 ON Table1.SomeField = Table2.SomeField, Setup
My Linq to SQL are like:
var q = from t1 in db.Table1
join t2 in db.Table2 on t1.SomeField equals t2.SomeField
join setup in db.Setup
select new {t1.MyField, setup.SomeField};
I'm getting an error on the last join that Type inference failed in the call to 'Join'.
Use SelectMany rather than a Join to perform a Cartesian Product.
In query syntax that would be:
var query = from t1 in db.Table1
from t2 in db.Table2
select new {t1, t2};
This will also do:
var q = from t1 in db.Table1
join t2 in db.Table2 on t1.SomeField equals t2.SomeField
from setup in db.Setup
select new {t1.MyField, setup.SomeField};