All combinations - LINQ query - c#

I have 3 tables(Objects in my OR mapping model, whatever). Let's call them TABLE1, TABLE2, and TABLE3 => actual names are in Czech, i think this will be better as example.
1)TABLE1 has 1-N relationship with TABLE2.
2)TABLE1 has also 1-N relationship with TABLE3. So the tables look something like this:
TABLE2
{
int ID;
nvarchar attributeT2;
int TABLE1_FK;
}
TABLE1
{
int ID;
}
TABLE3
{
int ID;
nvarchar attributeT3
int TABLE1_FK;
}
Now i need all combinations of: TABLE2 records where attributeT2 == "T2" and TABLE3 records where attributeT3 == "T3" BUT those two must have the same TABLE1_FK(= they must be joined by TABLE1 record).
So if there were 2 records in TABLE2 with TABLE1_FK ==1, and 2 records in TABLE3 with TABLE1_FK == 1, i need all combinations == 4 pairs. I could do this by foreach cycle, and querying the DB in each step, but i think that would be very ineffective, and i was wondering if there was a better way.
I thought it could be something like this:
var query= from x in context.TABLE2
where x.attributeT2 == "T2"
join y in context.TABLE3 on x.TABLE1_FK == y.TABLE1_FK
where y.attributeT3 == "T3"
select new WrapperClass(x,y);
But the combinations are wrong - the pair does not always have the same TABLE1_FK. Thanks a milion for any response.

I didn't check it myself, but maybe worths to try. The idea is to join on FK columns in TABLE2 and TABLE3 and have where condition for attibuteT3 and attributeT2
var query= from x in context.TABLE2
join y in context.TABLE3 on x.TABLE1_FK == y.TABLE1_FK
where y.attributeT3 == "T3" && x.attributeT2 == "T2"
select new WrapperClass(x,y);

I am SO sorry, but 2 minutes after i'd hit the submit button, i thought of something i haven't tried.
var asdf = from x in context.TABLE1
join y in context.TABLE2 on x.ID equals y.TABLE1_FK
where y.attributeT2 == "T2"
join z in context.TABLE3S on x.ID equals z.TABLE1_FK
where z.attributeT3 == "T3"
select new WrapperClass(y,z);
It worked. Thanks a lot anyway Michael.

Related

How to JOIN two data tables using LINQ and Where condition?

I have two data tables as following
TableA TableB
UID QID
QID Value1
Value2
I want to join two data tables and get Value1 and Value 2. I tried the following, but I am not getting any data back.
string str = "AAA";
var result = (from t1 in TableA.AsEnumerable()
//join between two tables
join t2 in TableB.AsEnumerable() on t1.Field<string>("UID") equals t2.Field<string>("QID")
//where conditions
where t2.Field<string>("QID") == str && t1.Field<string>("QID") == "ABCD"
//select clause
select t2.Field<string>("Value1"));
This is my query with out using LINQ and its working.
Select t2.Value1, t2.value2 from TableA t1 JOIN TableB t2 ON t2.QID = t1.UID WHERE t2.QID = 'AAAAA' AND t1.QID = 'XXXX'
Thanks for your help.
Your LINQ code should work, I guess you just need to use the same where the condition values for QID.
where t2.Field<string>("QID") == "AAA" && t1.Field<string>("QID") == "ABCD"
is not equal to your SQL:
WHERE t2.QID = 'AAAAA' AND t1.QID = 'XXXX'
It should work when you set correct values in LINQ

Entity Framework / LINQ: Left join defaultifempty fails

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

LINQ to SQL Join orderby

i am new to LINQ and joins, so Please forgive me if I am asking it wrong.
I have two tables
Table1
id name date
1 Mike 20-10-15
2 John 21-10-15
3 Sam 23-10-15
Table2
id name date
1 Ashle 19-10-15
2 Lily 21-10-15
3 Jeni 22-10-15
4 April 23-10-15
I need 5 records using Joins and should be orderby Date, most recent records.
Can you guys help me, I really need to figure out how Joins works with orderby.
Thanks
EDIT:
They are two different tables so no foreign key, so I think I can't use Join, so so far what I have done is like this
var combinddata = (from t1 in db.Table1
select t1.id)
.Concat(from t2 in db.Table2
select t2.id);
I don't know how to get only 5 records how to compare records from both tables on DateTime base.
Output should be
Sam
April
Jeni
John
Lily
You can concatenate equal anonymous types from different tables. If you also select the dates, you can sort by them, in descending order, and take the first 5 records:
Table1.Select (t1 =>
new
{
Id = t1.Id,
Name = t1.Name,
Date = t1.Date
}
).Concat(
Table2.Select (t2 =>
new
{
Id = t2.Id,
Name = t2.Name,
Date = t2.Date
}
))
.OrderByDescending (x => x.Date).Take(5)
Note that this gives precedence to items in Table1. If item 5 and 6 in the concatenated result are on the same date, but from Table1 and Table2, respectively, you only get the item from Table1.
If you want, you can select only the names from this result, but I assume that your output only shows the intended order of record, not the exact expected result.
var query =
from Table1 in table1
join Table2 in table2 on table1.id equals table2.id
orderby table1.date ascending
select table1.date;
Try this way
var combinddata = (from t1 in db.Table1
select t1.Name)
.Concat(from t2 in db.Table2
select t2.Name).OrderByDescending(x => x.date).Take(5);

Select from multiple tables using linq

I am trying to execute the following SQL statement using linq:
SELECT TTT.SomeField
FROM Table1 as T, Table2 as TT, Table3 as TTT
WHERE (T.NumberID = 100 OR T.NumberID = 101)
AND T.QuestionID = 200
AND T.ResponseID = TT.ResponseID
AND TT.AnswerID = TTT.AnswerID
Essentially getting one field from a third table based on primary/foreign key relationships to the other 2 tables. It is expected to have a single result every time.
var query = from t in db.Table1
join tt in db.Table2 on t.ResponseID equals tt.ResponseID
join ttt in db.Table3 on tt.AnswerID equals ttt.AnswerID
where (t.NumberID == 100 || t.NumberID == 101) && t.QuestionID == 200
select ttt.SomeField
If you always expect single result, you can wrap this in ().Single(), or, if there might be no results found, in ().SingleOrDefault().
If I understand you correct. You should read something about Joins I guess.
here

LINQ equivalent for SQL

I am trying to convert a ASP.NET project to Entity framework. How to re-write the following query to its LINQ equivalent?
SELECT {Table1 objects}
FROM [Table1] tb1
INNER JOIN [Table2] tb2
ON tb1.Table1ID = tb2.fk_Table1ID
WHERE tb2.fk_attrib1 = '123' AND tb2.fk_attrb2 = '345'
ORDER BY tb1.attrib1
The result is a collection of Table1 objects.
Here Table1 and Table2 correspond to object System.Data.Objects.ObjectSet of ADO.NET Entity Framework.
var results = from tb1 in Context.Table1
join tb2 in Context.Table2 on tb1.Table1ID == tb2.fk_Table1ID
where tb2.fk_attrib1 == "123" && tb2.fk_attrb2 == "345"
orderby tb1.attrib1
select tb1;
Something like this:
context.Table1
.Where( o => o.Table2s.Any( o2 =>
o2.fk_attrib1 == '123' &&
o2.fk_attrib2 == '345' ) )
.OrderBy( o => o.attrib1 )
.ToList();
BTW, LINQPad is great for trying out L2E queries.
This should help you a little bit. I suppose the main problem is with JOIN clause - in EF you can use NavigationProperties and don't need to worry about joining tables - EF will take care of that for you.
Also you are trying to filter on column from joined table. This you can do using Any method to find all Table1 elements that are connected to Table2 where those referenced elements have certain properties/columns. You should also get familiar with All method, as it might be useful to you in future.
from t1 in context.Table1
where t1.Table2s.Any(t2.fk_attrib1 == "123" && t2 => t2.fk_attrb2 == "345")
order by t1.attrib1
select t1;
Edit:
I assume that there is 1:n relationship between Table1 and Table2 which results in enumerable collection as NavigationProperty in Table1 objects.
Edit2:
Fixed error in code - didn't noticed that both attributes are from Table2 not Table1
Should be something like this:
var result = (from tb1 in Table1
from tb2 in Table2
where tb1.Key == tb2.Key &&
tb2.fk_attrib1 = '123' &&
tb2.fk_attrb2 = '345'
select ione).OrderBy(p=>p.attrib1);
Hope this helps.

Categories

Resources