Linq to DataSet Order By Clause Error - vb.net

I have following code that creates Linq query.
I've never used Linq until today (shame on me) and having problem with "Order By Clause"
Dim products = dt.AsEnumerable()
Dim linq = From p In products _
Where p!Weight > 2 _
Take 20 _
Select p!Clarity, p!Color, p!Weight _
Order By p!Weight.Length
If I run the code, I get following error.
Name 'p' is either not declared or not in the current scope.
How come p!Weight in "Select Clause" works but not in "Order By Clause"?
Thank you

After the Select clause, p is no longer in scope.
Move the Order By first.

Related

Sql syntax working in MS Access, but not in Visual Basic

This is my first time posting so I'm sorry if I make any mistakes.
So I have a database in access and I am trying to get the top 10 Client ID, the number of reservations made by the client and the sum of those reservations.
I have this Sql code in MS Access and it works there, but when I enter it in Visual Basic, I get te following error.
SQL syntax:
SELECT top 10 Clienti.CodCl, sum(Rezervari.SumaTotala) ,
count(Rezervari.CodRezervare)
FROM Clienti
INNER JOIN Rezervari ON (Clienti.CodCl = Rezervari.CodCl)
where datarezervarii BETWEEN #6/21/2020# AND #6/23/2020#
group by Clienti.CodCl
order by sum(Rezervari.SumaTotala) desc
The result table in access
Visual basic error :
System.Data.OleDb.OleDbException: 'The SELECT statement includes a
reserved word or an argument name that is misspelled or missing, or
the punctuation is incorrect.'
Thank you.
I managed to solve the problem. For anyone looking for the same answer, this is the code that i have used:
Dim top1 As String
top1 = "SELECT top 10 Clienti.CodCl, sum(Rezervari.SumaTotala) as suma, count(Rezervari.CodRezervare) FROM
Clienti INNER JOIN Rezervari ON Clienti.CodCl = Rezervari.CodCl where rezervari.datarezervarii BETWEEN #" & Inceput & "# AND #" & Sfarsit & "# group by Clienti.CodCl order by sum(Rezervari.SumaTotala) desc"
Dim cmdtop1 As New OleDbCommand(top1, con)
Dim dstop1 As New DataSet
Dim datop1 As New OleDbDataAdapter(cmdtop1)
datop1.Fill(dstop1, "Clienti INNER JOIN Rezervari ON Clienti.CodCl = Rezervari.CodCl")
Dim readtop1 As OleDbDataReader
readtop1 = cmdtop1.ExecuteReader
readtop1.Read()
Blockquote
Give an Alias to the aggregated fields. It's likely that .NET do not call them "Expr1001" and if inthe code you are referring to them you get the error.

linq query from one to many to many not letting me retrieve last many

I have a jobmain table which has a single jobnumber for every job, then a jobparts table which has many jobparts for each job, then a jobpartsforms which has many forms for every job part. Linq only allows the following:
Dim query = From jst In db.JobMains _
Where jst.JobNum = CInt(Session("JobNumber")) _
Select jst.JobParts
but I want to get the jobpartsforms which should look like this:
Dim query = From jst In db.JobMains _
Where jst.JobNum = CInt(Session("JobNumber")) _
Select jst.JobParts.JobPartsForms
How can I do this and why doesn't it work the way I think it should since the relationships are all built in already?
You need to flatten the query before selecting the JobPartsForms.
Dim query = From jst In db.JobMains _
Where jst.JobNum = CInt(Session("JobNumber")) _
From part in jst.JobParts _
Select part.JobPartsForms
Or with lambda syntax you can use SelectMany:
db.JobMains _
.Where(Funtion(j) j.JobNum = CInt(Session("JobNumber")) _
.SelectMany(Funtion(j) j.JobParts) _
.Select(Function(jp) jp.Forms)

Expected function / variable error message

i am trying to write a simple append query using SQL for my access database. Upon trying to execute the code, the message i am getting is:
Complilation error. Exepected function or variable
The query is a query which joins 4 tables and pastes the fields into another table. When using a standard MS Access query it works fine. I then generated and copied the SQL code (below) but unfortunately cannot get the query to work.
A final note about something strange. Unlike all the other SQL queries i have successfully written, this one, upon writing the Application.DoCmd.RunSQL (st_sql) into VBA, the space between the "L" and the "(st_sql) for some reason gets truncated.. Strange, this doesnt happen for any other string in the Whole routine where i successfully have other append queries.
Below is the code:
st_sql = "INSERT INTO[tblContactReporting03]([ID Project],[tblProjManagementPhaseHierarchy],[tblProjManagementSubPhaseHierarchy],[ID_Event],[SubTask_Hierarchy],[Project],[Sub project],[Project_Phase],[Project_Sub_Phase],[ContactFullName],[Role_Type],[type],[Event],[Effective_date],[Commitment],[Sub_task_name],[Status],[Notes])" & _
"SELECT[tblProjectMasterList].[ID Project],[tblProjManagementPhase].[Hierarchy],[tblProjManagementSubPhase].[Hierarchy],[tblContactReporting02].[ID_Event],[tblContactReporting02].[SubTask_Hierarchy],[tblProjectMasterList].[Project],[tblProjectMasterList].[Sub project],[tblProjManagementPhase].[Project_Phase],[tblProjManagementSubPhase].[Project_Sub_Phase],[tblContactReporting02].[ContactFullName],[tblContactReporting02].[Role_Type],[tblContactReporting02].[type]," & _
"[tblContactReporting02].[Event], [tblContactReporting02].[Effective_date],[tblContactReporting02].[Commitment],[tblContactReporting02].[Sub_task_name],[tblContactReporting02].[Status],[tblContactReporting02].[Notes]" & _
"FROM[tblProjectMasterListINNER JOIN ([tblProjManagementPhase] INNER JOIN ([tblContactReporting02] INNER JOIN [tblProjManagementSubPhase] ON [tblContactReporting02].[ID_Project_Sub_Phase] = [tblProjManagementSubPhase].[ID_Project_Sub_Phase]) ON ([tblContactReporting02].[ID_Project_Phase] = [tblProjManagementPhase].[ID_Project_Phase]) AND ([tblProjManagementPhase].[ID_Project_Phase] = [tblProjManagementSubPhase].[ID_Project_Phase])) ON [tblProjectMasterList].[ID Project] = [tblProjManagementPhase].[ID_Project]" & _
"ORDER BY [tblProjectMasterList].[ID Project], [tblProjManagementPhase].[Hierarchy], [tblProjManagementSubPhase].[Hierarchy], [tblContactReporting02].[ID_Event], [tblContactReporting02].[SubTask_Hierarchy];" & _
Application.DoCmd.RunSQL(st_sql)
I'd recommend a Debug.Print st_sql before running so that you'll be able to debug the constructed SQL.
The error you're getting is because RunSQL is a sub, not a function, so you need to call it 1) without parentheses:
Application.DoCmd.RunSQL st_sql
or 2) preceed it with Call and use parentheses:
Call Application.DoCmd.RunSQL(st_sql)
You can use syntax 2 for functions that when you don't need to use their return value.

LINQ - left join to find unmatched records

I'm trying to execute a left join between 2 datatables that will return all records from the left table without a corresponding value in the right table on the join criteria. As of now I have the following which returns nothing:
Dim Query1 = From exasset In dtExistingAssets _
GroupJoin asset In dtNewAssets _
On exasset("ACCOUNT_NAME") Equals asset("ACCOUNT_NAME") _
Into results = Group _
From f In results.DefaultIfEmpty _
Where IsDBNull(f) _
SelectNewWith _
{ //...
I've seen several references to using Any but I wasn't able get the syntax correct. Can anyone please help out? This is something that is really simple to accomplish in SQL but seems a lot more complicated in LINQ.
I think the problem is the IsDBNull(f), a left join will result in a null value (Nothing in VB) not a DBNull value. I think you should change it to: ``
...
From f In results.DefaultIfEmpty _
Where f is Nothing
I would use the strongly typed DataRow extension methods like Field which also support nullables.
Dim query = From exAsset In dtExistingAssets
Group Join newAsset In dtNewAssets
On exAsset.Field(Of String)("ACCOUNT_NAME") Equals newAsset.Field(Of String)("ACCOUNT_NAME") Into Group
From joinedAssets In Group.DefaultIfEmpty()
Where joinedAssets.Field(Of String)("ACCOUNT_NAME") Is Nothing
If you just want to know the new accounts, you can also use the efficient Enumerable.Except:
Dim existingAccounts = From exRow In dtExistingAssets
Select exRow.Field(Of String)("ACCOUNT_NAME")
Dim newAccounts = From newRow In dtNewAssets
Select newRow.Field(Of String)("ACCOUNT_NAME")
Dim newAccNotInExisting = newAccounts.Except( existingAccounts )

Datatable Grouping Using Linq and VB .NET

I'm completely dense here, but I'm trying to get some stats from a DataTable. One of the columns in the datatable is called "colour".
I need to find out how many of each instance of "colour" are in the datatable.
I'm trying:
Dim q = From p In PGWorkingDataTable _
Group p By p("colour") Into Group _
Select Group
But I get the compiler error at design-time:
"Range variable name can be inferred only from a simple or qualified name with no arguments" on the p("colour") section.
I need some serious guidance here. Thanks for your help.
Joe
You need to specify a name for the group key:
From p In new DataTable() _
Group p By Color = p("colour") Into Group _
Select Group
Writing LINQ in VB.NET is nobody's favorite thing. Try something like the following:
Dim q = From p In PGWorkingDataTable _
Group By colour = p("colour") _
Into colourCount = Count(p("colour")) _
Select colour, colourCount