Inner join in Linq with more than 2 datatables - linq

i have 3 tables
t1==>
t1.ID t1.co1 t1.col2
1 a b
2 a b
t2==>
t2.ID t2.co1 t2.col2
1 a b
2 a b
t3==>
t3.ID t3.co1 t3.col2
1 a b
2 a b
i want inner join between all three tables using Linq and want selected column in 4th datatable.
equivalent sql query:
SELECT t1.ID,t2.col1,t3.col2
FROM t1
INNER JOIN t2 ON t1.ID=t2.ID
INNER JOIN t3 ON t1.ID=t3.ID
t4==>
t1.ID t2.co1 t3.col2
1 a b
2 a b

Something like this
var Result =
from row1 in t1
join row2 in t2 on row1.ID equals row2.ID
join row3 in t3 on row1.ID equals row3.ID
select new { ID = row1.ID, Col1 = row2.col1, Col2 = row3.col2 }
DataTable dt = Result.CopyToDataTable();

Use LoadDataRow() to get a DataTable from an anonymous type as here. Else Result.CopyToDataTable().
//Get the column list as same as table1 to new datatable
DataTable table4 = table1.Clone();
var Result =
from x in t1.AsEnumerable() join
y in t2.AsEnumerable() on x.Field<int>("ID") equals y.Field<int>("ID") join
z in t3.AsEnumerable() on x.Field<int>("ID") equals z.Field<int>("ID")
select new table4.LoadDataRow(
new object[] {
x.ID,
y.col1,
z.col2
}, false);

Related

SQL Update with Join and Sub Query

I have the following queries and have trouble putting them together:
DECLARE #Value1 INT = 3
DECLARE #Value2 INT = 6
UPDATE TableA SET
Column1 = B.NewValue,
FROM TableA A INNER JOIN TableB B ON A.NumberId = B.NumberId AND
AND A.Type = #Value1
UPDATE TableA SET
Column2 = B.NewValue,
FROM TableA A INNER JOIN TableB B ON A.NumberId = B.NumberId AND
AND A.Type = #Value2
My goal is to have one query with a join that updates the columns depending on the values in the join.
This I just an example (in my case there are more columns and therefore more queries) but overall I want to have as few queries as possible (in this example: one query instead of two)
DECLARE #Value1 INT = 3
DECLARE #Value2 INT = 6
UPDATE TableA SET
Column1 = B.NewValue, --if the join joins on #Value1
Column2 = B.NewValue, --if the join joins on #Value2
FROM TableA A INNER JOIN TableB B ON A.NumberId = B.NumberId AND
AND A.Type = B.#Value1/#Value2
Is this possible (using a sub query for example)?
You can try using CASE EXPRESSION
UPDATE TableA SET
Column1 = CASE WHEN A.Type = #Value1 THEN B.NewValue
ELSE A.Column1 END,
Column2 = CASE WHEN A.Type = #Value2 THEN B.NewValue
ELSE A.Column2 END
FROM TableA A INNER JOIN TableB B ON A.NumberId = B.NumberId AND
AND A.Type IN (#Value1, #Value2)

How count table a data for every data of table a

I have three table A,B,C.
A table:
id,name
B table:
id,a_id,date
C table:
id,b_id,type(value is 0/1)
I want to print all A.name,A.id and C.countingdata by counting C data where C.type=1 using B table which has A table id
Result look like below:
A.id A.name C.countingdata
1 abc 4
2 vfd 2
3 fdg 0
Well, you can first inner join B and C, do the group by and get C.countingdata using count(). Another join on this subquery with B itself to accommodate the a_id
in the result set.
Now, you can do an inner join between A and the above subquery to get your results.
SQL:
select A.id, A.name, derived.countingData
from A
inner join (
select B.id as b_id,B.a_id,sub_data.countingData
from B
inner join (
select B.id,count(B.id) as countingData
from B
inner join C
on B.id = C.b_id
where C.type=1
group by B.id
) sub_data
on B.id = sub_data.id
) derived
on A.id = derived.a_id
You can find query as below:
Select
A.id
,A.name
,COUNT(C.id)
FROM A
JOIN B ON A.id = B.a_id
JOIN C ON B.id = C.b_id ANd C.type = 1
GROUP BY
A.id
,A.name

linq query to return 1 row with complex values instead of 2

var query = from t1 in Context.Table1
join t2 in Context.Table2 on t1.Id equals t2.Id
join t3 in Context.Table3 on t3.Id equals t1.Id
join t4 in Context.Table4 on t1.Id equals t4.Id into temp
from temp_values in temp.DefaultIfEmpty()
where t1.Id == id
select new
{
Field1 = t1.Id,
Field2 = t1.Field2,
SpecialField = t4.temp_values
};
I have this Linq query that returns 2 rows, because of the last join with Table4.
Notice that both rows have the same values on Field1 and Field2.
Any smart way to return instead just 1 row, that has SpecialField marked as a List that has all the temp_values stores in it?
so instead of:
Field1 / Field2/ SpecialField
1 /2 /{ Id=1, Prop1=2, Prop1=3}
1 /2 /{ Id=2, Prop1=12, Prop1=13}
I want:
Field1 / Field2/ SpecialField
1 /2 /List with 2 entries: { Id=1, Prop1=2, Prop1=3}, { Id=2, Prop1=12, Prop1=13}

Left join to a SET using linq

In SQL, I would commonly inner join two or more tables to create a set and then left join to that set:
select *
from TableA
left outer join
TableB
inner join TableC on TableB.Id = TableC.TableBId
on TableA.Id = TableB.TableAId
What is the Linq equivalent of this? I'm using EF Code First.
Like this:
var result = from a in TableA
join b in TableB on a.Id equals b.TableAId into ab
from b in ab.DefaultIfEmpty()
join c in TableC on b.Id equals c.TableBId
select a;
I was able to achieve this by breaking it into two statements. First, make your inner join set, then left join to that set.
var bc = from b in TableB
join c in TableC on b.Id equals c.TableBId
select new { B = b, C = c };
var result = from a in TableA
from bcRow in bc.Where(row => a.Id equals row.B.TableAId).DefaultIfEmpty()
select new { A = a, B = bcRow.B, C = bcRow.C };

Linq and foreign key Lookup tables with integer keys

I have a database where the tables are:
Table1:
Table1Id int
Table2:
Table2Id int
ForeignKeyToTable1 int
LookupTable:
Table2Id
Table3Id
Table3:
Table3Id int
Table3Field varchar
I want to:
select table1.* from table1
inner join table2 on table1.Table1Id = ForeignKeyToTable1
inner join LookupTable on LookupTable.Table2Id = table2.Table2Id
inner join Table3 on table3.Table3Id = LookupTable.Table3Id
where table3.Table3Field ='qwerty'
How can this be achieved in Linq?
var query =
from table1 in db.Table1
join table2 in db.Table2 on new { Table1Id = table1.Table1Id } equals new { Table1Id = table2.ForeignKeyToTable1 }
join lookuptable in db.LookupTable on table2.Table2Id equals lookuptable.Table2Id
join table3 in db.Table3 on lookuptable.Table3Id equals table3.Table3Id
where
table3.Table3Field == "qwerty"
select new {
table1.Table1Id
};
I believe something like this will go
var query = from t1 in context.Table1
join t2 in context.Table2
on t1.Table1Id equals t2.ForeignKeyToTable1
join lt in context.LookupTable
on t2.Table2Id equals lt.Table2Id
join t3 in context.Table3
on lt.Table3Id equals t3.Table3Id
where t3.Table3Field == "qwerty"
select t1;

Resources