Select two datacolumns from a datarow in linq (vb.net 3.5) - vb.net

Dim orders = From tt In testTable _
Order By tt.Item("OrderNumber") _
Select tt.Item("OrderNumber"), tt.Item("OrderId")
This is breaking. Is there a way to do this? I would have thought it was easy enough. Obviously, I thought wrong....

Dim orders = From tt In testTable _
Order By tt.Item("OrderNumber") _
Select New With {.OrderNo = tt.Item("OrderNumber"), .OrderId = tt.Item("OrderId")}
If I got the VB.NET syntax right
This returns an anonymous type, if you want to return an existing type you replace With with that type.

Related

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

Linq join typeddatatable with List and return typeddatatable

I hava a strongly typed datatable and a list(of String).
I want to build a linq query to return a datatable of the same type where the fields of a certain column of the table are in the list. I thought of doing a Join, although in normal sql I would have added
SELECT FROM Table WHERE Table.ID IN(...);
This is what I tried in linq.
Dim Families As List(Of String)
Dim Articles As SomeStronglyTypedDataTable
Dim MatchingArticles = From a In Articles.AsEnumerable _
Join f In Families.AsEnumerable On a.FamilyCode Equals f.ToString _
Select New With {}
I'm not sure either if I need to convert the query result back to a datatable nor if that's even possible.
Thanks!
Try the simpler query:
Dim MatchingArticles = From a In Articles.AsEnumerable _
Where Families.Contains(a.FamilyCode)_
Select a
Dim MyMatchingArticlesTable = CopyToDataTable(Of SomeStronglyTypedDataTable) (MatchingArticles)
Yes, you can do this. Instead of Select New ..., select the matching DataRows, Select a, and then use CopyToDataTable(Of T) on the matching rows.
Dim table As DataTable = query.CopyToDataTable()
Dim typedtable As New TypedDataset.TypedDataTable
typedtable.Merge(table)
I was raking my brain trying to get something similar to work, and your code enlightened me.
All I needed was to add the .AsEnumerable() on both sides.
I'm working with C#. Anyway, I think all you need to do is select your table like
Dim MatchingArticles = From a In Articles.AsEnumerable _
Join f In Families.AsEnumerable On a.FamilyCode Equals f.ToString _
Select a;
Well, this is a very old post, but hey, it might help someone else...
If you think this would resolve your question, please mark it as correct, so others will know. You may also want to mark Devart's answer as correct. I tried it and it works.

linq sum in vb.net

I need to make a query that look like this is SQL:
SELECT CodProiect, SUM(Valoare)
FROM DET
WHERE CodProiect = 'cod_pr'
GROUP BY CodProiect;
How can I write the same thing in LINQ?
I have attempted this:
dim gac1 = (From ac1 In t_detalii _
Where ac1!CodProiect = cod_pr1 _
Select ac1!Valoare).Sum(Function(ac1) ac1!Valoare)
But it gives me an error "No default member found for type 'Double'."
You need to select ac1 instead of ac1!Valoare (which is the property itself, not the corresponding object)
dim gac1 = (From ac1 In t_detalii _
Where ac1!CodProiect = cod_pr1 _
Select ac1).Sum(Function(ac1) ac1!Valoare)
edit
You can of course group it in the query already:
dim gac1 = (From ac1 In t_detalii _
Where ac1!CodProiect = cod_pr1 _
Group By ac1.CodProiect Into ac2
Select ac2.Sum(Function(ac2) ac2!Valoare)
(something in that direction, I'm not familiar with the vb.net syntax, also I'm writing it without compilersupport atm.

Linq to XML. Selecting Multiple columns

Dim MyQuery = From c In xdoc.Descendants() _
Where c.Attribute(OriginY) IsNot Nothing _
Order By Val(c.Attribute(OriginY).Value), Val(c.Attribute(OriginX).Value) _
Select c.Attribute(UniStr)
Right above you can see my First! linq attempt! And here comes my first question.
How can i select more than one column in a linq query in vb.net?
For example... Select c.Attribute(UniStr) AND c.Attribute(OriginY)
Not really a VB.NET person, but this should work (Providing your existing statement compiles):
Dim MyQuery = From c In xdoc.Descendants() _
Where c.Attribute(OriginY) IsNot Nothing _
Order By Val(c.Attribute(OriginY).Value), Val(c.Attribute(OriginX).Value) _
Select UniStr = c.Attribute(UniStr), OriginY = c.Attribute(OriginY)
You should read about Projections in VB.NET and LINQ.