Need help with an Opposite to Inner join Query using LINQ - c#

I have two tables in an XML Dataset. T1, T2. Each of the tables has a ID column.
T1 has a list of Customers
T2 has a list of Orders
I want to build a LINQ query that returns only the ID of the customers that do not have orders. In other words customer ID's that do not exist in the T2 table.
Oh yea, I'm using C#
Thanks!

This requires an outer join and a check on null.
var result = from c in Customers
join d in Details on d.CustomerID equals c.ID into g
where !g.Any()
select c;

I think this will work (please adapt to your DataSets):
var query = from c in T1
where !(from o in T2 select o.CustomerID)
.Contains(c.CustomerID)
select c;

You just need to us a where clause and all:
T1.Where( item1 => T2.All( item2 => item1.ID != item2.ID ) );

Related

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);

How do I write an exists subquery using multiple columns in LINQ?

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;

Linq to SQL: How to join on no field i.e. cartesian join

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};

Multiple table join with multiple table where clause

I have a query that's something like this.
Select a.*
from table1 a
inner join table2 b on a.field1 = b.field1
inner join table3 c on b.field2 = c.field2
where b.field4 = beta and c.field5 = gamma.
On LINQ, I tried to do that this way:
var query = (from a in table1
join b in table2 on a["field1"] equals b["field1"]
join c in table3 on b["field2"] equals c["field2"]
where (b["field4"] == beta && c["field5"] == gamma)
select a).ToList();
But for some reason, when I try to do this I get an error that says that the entity "table2" doesn't have the field Name = "field5", as though as the where clause was all about the last joined table and the other ones were unaccessible. Furthermore, the compiler doesn't seem to notice neither, because it lets me write c["field5"] == gamma with no warning.
Any ideas? Am I writing this wrong?
Thanks
See these links:
How to: Perform Inner Joins (C# Programming Guide)
What is the syntax for an inner join in linq to sql?
Why you don't create View in database, and Select your data from View in LINQ?

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