Inner join using LINQ on DataTables - c#

I have these 2 DataTables, customerTableDT and customerAliasesTableDT. They are both populated from a database like this:
customerTableDT = UtilityDataAndFunctions.PerformDBReadTransactionDataTableFormat(String.Format("SELECT * FROM {0}", TableNames.customers));
customerAliasesTableDT = UtilityDataAndFunctions.PerformDBReadTransactionDataTableFormat(String.Format("SELECT * FROM {0}", TableNames.customerAliases));
Now I'm trying to do an inner join on the two datatables like this:
var customerNames = from customers in customerTableDT.AsEnumerable()
join aliases in customerAliasesTableDT.AsEnumerable on customers.Field<int>("CustomerID") equals aliases.Field<int>("CustomerID")
where aliases.Field<string>("Alias").Contains(iString) select customers.Field<string>("Name")
But it gives me this error:
The type of one of the expressions in the join clause is incorrect. Type inference failed in the call to 'Join'.
If I had to write in SQL about what I'm trying to do, its very simple:
SELECT * FROM CUSTOMERS C
INNER JOIN CustomerAliases ALIASES ON ALIASES.CustomerID = C.CustomerID
WHERE CA.Alias LIKE %STRING_HERE%
Any help ?

You missed brackets after AsEnumerable, so it's treated as Method Group, not IEnumerable<DataRow>:
var customerNames = from customers in customerTableDT.AsEnumerable()
join aliases in customerAliasesTableDT.AsEnumerable() on customers.Field<int>("CustomerID") equals aliases.Field<int>("CustomerID")
where aliases.Field<string>("Alias").Contains(iString) select customers.Field<string>("Name")

Related

Linq query showing more data than the SQL alternative

I have an linq query like this :
var query = from Romm in RoMM
join rfrsa in RoMmfrsa on Romm.RoMmid equals rfrsa.RoMmid
join frsa in Frsa on rfrsa.Frsaid equals frsa.Fraid
join fra in Fra on frsa.Fraid equals fra.Fraid
where Romm.ActTypeId == 2 && Romm.SegmentId == 4
select new
{
Romm.ActTypeId,
Romm.RoMmid,
frsa.Fraid,
frsa.Frsaid,
Romm.ImpactId
};
And I have SQL code as below :
SELECT romm.ROMMID
, frsa.FRAID
, frsa.FRSAID
, romm.ImpactID
FROM RoMM AS romm
INNER
JOIN RoMMFRSA AS rfrsa
ON romm.RoMMID = rfrsa.RoMMID
INNER
JOIN FRSA AS frsa
ON rfrsa.frsaid = frsa.frsaid
INNER
JOIN FRA AS fra
ON frsa.FRAID = fra.FRAID
WHERE romm.acttypeid = 2
AND romm.segmentid = 4
The SQL only shows one row (which is correct), the linq shows the correct row and then it displays about another 3 rows which is not what we need. I need the linq to show one row which is correct with the SQL. Is this because of maybe many-many relationships ?
Looks like a typo in either the C# or the SQL join:
SQL: ON rfrsa.frsaid = frsa.frsaid
C#: rfrsa.Frsaid equals frsa.Fraid
^^^^^^
mismatch here

Syntax Error (Missing Operator) in query expression with Multiple Inner Join in C# MS Access

I am using Inner Join to Join 3 Tables. But when I execute this, I got error
Syntax Error (Missing Operator) in query expression 'a.Group_ID = b.Group_ID INNER JOIN VendorList AS c ON a.Vendor_Id = c.Vendor_I'
How do I use multiple inner joins in C# with MS Access?
str = "Select a.ID, b.Group_Name, a.Voucher_No, a.Bill_No, a.Date, c.Vendor_Name, a.Amount FROM BillTable a INNER JOIN GroupName AS b ON a.Group_ID = b.Group_ID INNER JOIN VendorList AS c ON a.Vendor_Id = c.Vendor_Id ";
da = new OleDbDataAdapter(str, cn);
That syntax, while accepted by any database more powerful than Access, is not quite right when you are dealing with JET Sql. In this case you need to add round brackets around each join group to help the JET parser understand the query.
So you need to write this one instead
str = #"Select a.ID, b.Group_Name, a.Voucher_No, a.Bill_No, a.[Date], c.Vendor_Name, a.Amount
FROM ((BillTable a INNER JOIN GroupName AS b ON a.Group_ID = b.Group_ID)
INNER JOIN VendorList AS c ON a.Vendor_Id = c.Vendor_Id) ";
Note that the most external pair of round brackets are not really required. I put them there just to show how to add them if more joins are required.
Also I think that a.Date will be the cause of another exception because Date is a reserved keyword. You will get a syntax error again. You can avoid it adding square brackets around Date like in a.[Date]

How to translate this inner join T-SQL into LINQ-to-Entities?

I have a snippet of Stored Procedure:
...
SELECT B.BinID, AverageCost, SUM(Qty) AS Qty
FROM #CurrentReturn R INNER JOIN Bins B ON R.BinCode = B.BinCode AND B.StoreroomID = #StoreroomID
...
#StorerroomID is one of the SP parameters.
Now I am trying to translate it into LINQ to Entities,
var AverageCostList = from r in CurrentReturn
join b in BinQuery on new {r.BinCode, b.StoreroomID} equals new {b.BinCode, storeroomID}
It does not work, as the type on the L.H.S. of equals cannot contains fields in b.
So is there any way to translate such an inner join SQL into LINQ?
i would put the B.StoreroomID = #StoreroomID comparison into ther where clause
from r in CurrentReturn
join b in BinQuery
on r.BinCode equals b.BinCode
where b.StoreroomID == storeroomID

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?

Can't convert T-SQL INNER JOIN to LINQ-Entities query

T-SQL:
declare #postlocations table (locationid int)
insert into #postlocations
select locationid
from dbo.PostLocations
where PostId = 162172
select t.*
from dbo.Themes t
inner join dbo.ThemeLocations tl on t.ThemeId = tl.ThemeId
inner join #postlocations pl on tl.LocationId = pl.locationid
LINQ-Entities i have so far:
var postLocations = e.SomePost.Locations; // pre-fetched, e.g materialized ICollection<Post>
var themes = (from t in db.Themes
join q in postLocations on t.Locations.Select(l => l.LocationId) equals q.LocationId
select t).ToList();
But the compiler is complaining on the join keyword about not being able to infer the type arguments.
Any ideas?
I don't think you can join a SQL table with an in-memory list of objects, even if those objects are originally from the database.
Convert the in-memory list of objects to a list of id's (integer), and use that in the join or in a Contains/sub-select. EF can translate the list of id's to parameters when generating the SQL.
The problem with your join is that you're implying a collection of LocationId (t.Locations.Select(l => l.LocationId) can equal a single LocationId. You're trying to join a Theme which has a collection of Locations onto a single Location.
You should be able to fix this by using Contains
var themes = (from t in db.Themes
join q in postLocations
on t.Locations.Select(l => l.LocationId).Contains(q.LocationId)
select t).ToList();
or if EF complains about passing a postLocations as a parameter, you can try
// I'd materialize this but you may not have to
var postLocationIds = postLocations.Select(p => p.LocationId).ToList();
var themes = db.Themes.Where(t => t.Locations.Any(l =>
postLocationIds.Contains(l.LocationId))).ToList();
Edit
how about this
///your sql query
select t.* from dbo.Themes t
inner join dbo.ThemeLocations tl on t.ThemeId = tl.ThemeId
inner join #postlocations pl on tl.LocationId = pl.locationid
//linq query for that
from t in teams
join from tl in teamlocation on t.themid = tl.ThemeID
join from pl in postlocation on tl.temeid = pl.temeid
select t;
Org
Not sure but you can try out by using let keyword
var themes = (from t in db.Themes
let location = t.Locations
join q in postLocations on location.LocationId equals q.LocationId
select t).ToList();

Categories

Resources