I have a database table that have a structure like this:
ID Integer Auto Incresement
Name VarChar
Status VarChar
Sample records:
ID Name Status
1 record 1 Outstanding
2 record 2 Outstanding
3 record 3 Aging
4 record 4 Outstanding
5 record 5 Aging
6 record 6 Outstanding
In the table, there are two main status: "Outstanding" and "Aging". I want to count how many records with status of "Outstanding" and how many records with status of "Aging" available in the table.
This is a sample LINQ Query:
Using DC = DataClassesDataContext.Create()
Dim dataTable = From Count(Outstanding), Count(Aging) In DC.MyTable _
Where item.Status = "Outstanding" OrElse item.Status = "Aging" _
Group By item.Status _
Select item
End Using
The expected result should be:
Outstanding Aging
4 2
Can you help me to design a LINQ to achive the result?
Try this:
Dim MyTable = { _
New With {.ID = 1, .Name = "record 1", .Status = "Outstanding"},
New With {.ID = 2, .Name = "record 2", .Status = "Outstanding"},
New With {.ID = 3, .Name = "record 3", .Status = "Aging"},
New With {.ID = 4, .Name = "record 4", .Status = "Outstanding"},
New With {.ID = 5, .Name = "record 5", .Status = "Aging"},
New With {.ID = 6, .Name = "record 6", .Status = "Outstanding"}
}
Dim dataTable = _
From item In MyTable
Group By Key = item.Status Into Xs = Group
Select New With {.Status = Key, .Count = Xs.Count()}
I get this result:
Try this :-
using System;
using System.Collections.Generic;
using System.Linq;
public class Program
{
public static void Main()
{
var test = new List<Sample>();
test.Add(new Sample{ID=1,Name="record 1",Status="Outstanding"});
test.Add(new Sample{ID=2,Name="record 2",Status="Outstanding"});
test.Add(new Sample{ID=3,Name="record 3",Status="Aging"});
test.Add(new Sample{ID=4,Name="record 4",Status="Outstanding"});
test.Add(new Sample{ID=5,Name="record 5",Status="Outstanding"});
test.Add(new Sample{ID=6,Name="record 6",Status="Aging"});
var result = from row in test
group row by "Count" into g
where g.FirstOrDefault() != null
select new
{
//Status = g.Key,
Outstanding = g.Where(C => C.Status == "Outstanding").Count(),
Aging = g.Where(C => C.Status == "Aging").Count()
};
Console.WriteLine("Outstanding"+" "+"Aging");
foreach(var item in result)
{
Console.WriteLine(" "+item.Outstanding+" "+item.Aging);
}
}
}
public class Sample
{
public int ID {get;set;}
public string Name {get;set;}
public string Status {get; set;}
}
result :-
you can run above sample code using following link - https://dotnetfiddle.net/xC2NXm
suggest improvement :)
I'm trying to join a table to itself using a group join and VB.NET. The code below works and sorts the outer (parent) rows but I'd like to guarantee the sequence of the inner (child) rows:
Dim queryEthnicities = From aParentEthnicity In edata.Ethnicity _
Group Join aChildEthnicity In edata.Ethnicity On aChildEthnicity.ParentID Equals aParentEthnicity.EthnicityID Into EthnicityList = Group _
Where aParentEthnicity.RoundID.Equals(aRoundID) Order By aParentEthnicity.Sort
I found something similar for C# at Ordering inner keysource in simple/unnamed C# LINQ group join
but haven't found a way to do this in VB - grateful for any ideas.
Here's what you need to provide when asking a question:
Public Class edata
Public Ethnicity As Ethnicity() = _
{ _
New Ethnicity() With { .EthnicityID = 4, .ParentId = 1, .RoundID = 3, .Sort = 8 }, _
New Ethnicity() With { .EthnicityID = 3, .ParentId = 1, .RoundID = 4, .Sort = 5 }, _
New Ethnicity() With { .EthnicityID = 1, .RoundID = 2 } _
}
End Class
Public Class Ethnicity
Public ParentID As Integer
Public EthnicityID As Integer
Public RoundID As Integer
Public Sort As Integer
End Class
Sub Main
Dim edata = New edata()
Dim aRoundID = 2
Dim queryEthnicities = _
From aParentEthnicity In edata.Ethnicity _
Group Join aChildEthnicity In edata.Ethnicity On aChildEthnicity.ParentID Equals aParentEthnicity.EthnicityID Into EthnicityList = Group _
Where aParentEthnicity.RoundID.Equals(aRoundID) _
Order By aParentEthnicity.Sort
End Sub
When this code runs it produces:
To ensure the order of the inner data you need to change the query like so:
Dim queryEthnicities = _
From aParentEthnicity In edata.Ethnicity _
Group Join aChildEthnicity In edata.Ethnicity.OrderBy(Function (x) x.Sort) On aChildEthnicity.ParentID Equals aParentEthnicity.EthnicityID Into EthnicityList = Group _
Where aParentEthnicity.RoundID.Equals(aRoundID) _
Order By aParentEthnicity.Sort
Now it produces:
Can anyone help me put this code into a nested loop please. It is a code to calculate the lowest score of candidates who have been ranked in order of preferences with 1 being the first preference and 5 being the highest.
Dim min = 0
If Candidate1total > min Then
min = Candidate1total
LabelWINNER.Text = EnterNames.Cand1Name.Text
End If
If Candidate2total < min Then
min = Candidate2total
LabelWINNER.Text = EnterNames.Cand2Name.Text
End If
If Candidate3total < min Then
min = Candidate3total
LabelWINNER.Text = EnterNames.Cand3Name.Text
End If
If Candidate4total < min Then
min = Candidate4total
LabelWINNER.Text = EnterNames.Cand4Name.Text
End If
If candidate5total < min Then
min = candidate5total
LabelWINNER.Text = EnterNames.Cand5Name.Text
End If
Candidate1Total to Candidate5Total are the total scores for the candidates. This is calculated by working out the number of times a user has voted for them. The name that the candidate was given on the ENTERNAMES form is then placed in the labelWINNER if that candidate is lower then the minuim.
I think it would be something like for 0 in candidate1 total, im not 100% certain, hence asking for help.
This is what I would do:
Dim Candidates = _
{ _
New With { .Candidate = EnterNames.Cand1Name.Text, .Total = Candidate1total }, _
New With { .Candidate = EnterNames.Cand2Name.Text, .Total = Candidate2total }, _
New With { .Candidate = EnterNames.Cand3Name.Text, .Total = Candidate3total }, _
New With { .Candidate = EnterNames.Cand4Name.Text, .Total = Candidate4total }, _
New With { .Candidate = EnterNames.Cand5Name.Text, .Total = Candidate5total } _
}
Dim result = _
Candidates _
.OrderBy(Function (c) c.Total) _
.GroupBy(Function (c) c.Total, Function (c) c.Candidate) _
.Select(Function (c) New With { .Candidate = String.Join(", ", c), .Total = c.Key }) _
.First()
So, to see the result, I used this example data:
Dim Candidates = _
{ _
New With { .Candidate = "Mike", .Total = 5 }, _
New With { .Candidate = "Tony", .Total = 2 }, _
New With { .Candidate = "Bill", .Total = 2 }, _
New With { .Candidate = "Carl", .Total = 3 }, _
New With { .Candidate = "Dick", .Total = 4 } _
}
I got this result:
Of course, if it were just one candidate with the lowest total score then there would only be one name in the Candidate field.
I am trying to write a linq query with a composite key. Here is the full query:
Dim qeRelationships = From p In qualificationElements _
Join r In relationships On New With {.ElementCode = r.Parent, .Type = r.ParentType} _
Equals New With {.ElementCode = p.ElementCode, .Type = p.Type} _
Join c In qualificationElements On New With {.ElementCode = r.Child, .Type = r.ChildType} _
Equals New With {.ElementCode = c.ElementCode, .Type = c.Type} _
Select New QualificationElementRelationship _
With {.Parent = p, _
.Child = c, _
.Relationship = r.RelationshipType, _
.Scope = r.Scope}
This is yielding no results and I am not sure why.
I have boiled it down to two examples. The following works and returns records:
Dim qeRelationships = From p In qualificationElements _
Join r In relationships On r.Child Equals p.ElementCode _
Select New _
With {.Relationship = r.RelationshipType, _
.Scope = r.Scope}
This next snippet does not work and does not return records
Dim qeRelationships = From p In qualificationElements _
Join r In relationships On New With {.a = r.Child} Equals New With {.a = p.ElementCode} _
Select New _
With {.Relationship = r.RelationshipType, _
.Scope = r.Scope}
Why does the first query work and the second fail?
Here is a quick post and answer! It is because all the properties of your anonymous class need to be marked up with the "Key" directive.
Dim qeRelationships = From p In qualificationElements _
Join r In relationships On New With {Key .a = r.Child} Equals New With {Key .a = p.ElementCode} _
Select New _
With {.Relationship = r.RelationshipType, _
.Scope = r.Scope}
The full query
Dim qeRelationships = From p In qualificationElements _
Join r In relationships On New With {Key .ElementCode = r.Parent, Key .Type = r.ParentType} _
Equals New With {Key .ElementCode = p.ElementCode, Key .Type = p.Type} _
Join c In qualificationElements On New With {Key .ElementCode = r.Child, Key .Type = r.ChildType} _
Equals New With {Key .ElementCode = c.ElementCode, Key .Type = c.Type} _
Select New QualificationElementRelationship _
With {.Parent = p, _
.Child = c, _
.Relationship = r.RelationshipType, _
.Scope = r.Scope}
I have 2 representations of similar data from 2 different systems and I need to match each entity in one system with the entities in the other.
System A is Hierarchical, represented as a Dictionary(Of String, List(Of CategoryA)) looking something like:
- "Organization 1"
- { Name = "Cat1", Id = 1}
- { Name = "Cat2", Id = 2}
- { Name = "Cat3", Id = 3}
- "Organization 2"
- { Name = "Cat1", Id = 4}
- { Name = "Cat3", Id = 5}
- { Name = "Cat4", Id = 6}
- "Organization 3"
- { Name = "Cat1", Id = 7}
- { Name = "Cat2", Id = 8}
- { Name = "Cat3", Id = 9}
- { Name = "Cat4", Id = 10}
System B is Flattened, represented as a List(Of CategoryB) looking something like:
- { Org = "Organization 1", Name = "Cat1", Id = 100 }
- { Org = "Organization 1", Name = "Cat2", Id = 101 }
- { Org = "Organization 1", Name = "Cat3", Id = 102 }
- { Org = "Organization 2", Name = "Cat1", Id = 103 }
- { Org = "Organization 2", Name = "Cat2", Id = 104 }
- { Org = "Organization 2", Name = "Cat4", Id = 105 }
- { Org = "Organization 4", Name = "Cat1", Id = 106 }
- { Org = "Organization 4", Name = "Cat2", Id = 107 }
- { Org = "Organization 4", Name = "Cat3", Id = 108 }
- { Org = "Organization 4", Name = "Cat4", Id = 109 }
And basically what I need to do is to outer join the hierarchical data to the flattened data on Organization name (Dictionary.Key to CategoryB.Org) and Category Name (CategoryA.Name to CategoryB.Name), leaving me with a Dictionary(Of String, IEnumerable(Of Tuple(Of CategoryA, CategoryB))) or something that looks something like:
- "Organization 1"
- { Name = "Cat1", Id = 1}, { Org = "Organization 1", Name = "Cat1", Id = 100 }
- { Name = "Cat2", Id = 2}, { Org = "Organization 1", Name = "Cat2", Id = 101 }
- { Name = "Cat3", Id = 3}, { Org = "Organization 1", Name = "Cat3", Id = 102 }
- "Organization 2"
- { Name = "Cat1", Id = 4}, { Org = "Organization 2", Name = "Cat1", Id = 103 }
- { Name = "Cat3", Id = 5}, null
- { Name = "Cat4", Id = 6}, { Org = "Organization 2", Name = "Cat4", Id = 105 }
- "Organization 3"
- { Name = "Cat1", Id = 7}, null
- { Name = "Cat2", Id = 8}, null
- { Name = "Cat3", Id = 9}, null
- { Name = "Cat4", Id = 10}, null
I don't have access to the CategoryA object to be able to apply an Organization property to it, or I would do it and make this easier on myself. I just can't figure out how to join on the Dictionary key and a property of one of the items in its value, and end up with anything useful. The most successful implementation I've created involves a For Each loop first, and a LINQ query inside:
Given:
catA = Dictionary(Of String, List(Of CategoryA))
catB = List(Of CategoryB)
Dim result As New Dictionary(Of String, List(Of Tuple(Of CategoryA, CategoryB)))
For Each kvp As KeyValuePair(Of String, List(Of CategoryA)) In catA
Dim orgName As String = kvp.Key
If Not result.ContainsKey(orgName) Then
result.Add(orgName, New List(Of Tuple(Of CategoryA, CategoryB)))
End If
Dim orgCategories As IEnumerable(Of CategoryB) =
From cat In catB Where cat.Org = orgName
Dim tmpResult As IEnumerable(Of Tuple(Of CategoryA, CategoryB)) =
From cat_a In kvp.Value
Group Join cat_b In orgCategories
On cat_a.Name Equals cat_b.Name
Into matchedCats = Group
From cat In matchedCats.DefaultIfEmpty
Select matches = Tuple.Create(cat_a, cat)
result(orgName).AddRange(tmpResult)
Next
It works alright, but I'd like it to be in the same statement.
Well, this kinda works but id stick with your for loop!
Public Class CategoryA
Public Property Name As String
Public Property Id As Integer
End Class
Public Class CategoryB
Public Property Org As String
Public Property Name As String
Public Property Id As Integer
End Class
Private SystemA As New Dictionary(Of String, List(Of CategoryA))
Private SystemB As New List(Of CategoryB)
Sub Main()
SystemA.Add("Org1", New List(Of CategoryA) From {New CategoryA() With {.Id = 1, .Name = "Cat1"},
New CategoryA() With {.Id = 2, .Name = "Cat2"},
New CategoryA() With {.Id = 3, .Name = "Cat3"}})
SystemA.Add("Org2", New List(Of CategoryA) From {New CategoryA() With {.Id = 4, .Name = "Cat1"},
New CategoryA() With {.Id = 5, .Name = "Cat2"},
New CategoryA() With {.Id = 6, .Name = "Cat3"}})
SystemA.Add("Org3", New List(Of CategoryA) From {New CategoryA() With {.Id = 7, .Name = "Cat1"},
New CategoryA() With {.Id = 8, .Name = "Cat2"},
New CategoryA() With {.Id = 9, .Name = "Cat3"},
New CategoryA() With {.Id = 10, .Name = "Cat4"}})
SystemB.Add(New CategoryB() With {.Org = "Org1", .Name = "Cat1", .Id = 100})
SystemB.Add(New CategoryB() With {.Org = "Org1", .Name = "Cat2", .Id = 101})
SystemB.Add(New CategoryB() With {.Org = "Org1", .Name = "Cat3", .Id = 102})
SystemB.Add(New CategoryB() With {.Org = "Org2", .Name = "Cat1", .Id = 103})
SystemB.Add(New CategoryB() With {.Org = "Org2", .Name = "Cat2", .Id = 104})
SystemB.Add(New CategoryB() With {.Org = "Org2", .Name = "Cat4", .Id = 105})
SystemB.Add(New CategoryB() With {.Org = "Org4", .Name = "Cat1", .Id = 106})
SystemB.Add(New CategoryB() With {.Org = "Org4", .Name = "Cat2", .Id = 107})
SystemB.Add(New CategoryB() With {.Org = "Org4", .Name = "Cat3", .Id = 108})
SystemB.Add(New CategoryB() With {.Org = "Org4", .Name = "Cat4", .Id = 109})
Dim AllOrgs = SystemA.Keys.Union(SystemB.Select(Function(b) b.Org).Distinct)
Dim BothCats2 = From org In AllOrgs
Let CatAList = If(Not SystemA.ContainsKey(org), New List(Of CategoryA), From cat In SystemA(org))
Let CatBList = (From cat In SystemB Where cat.Org = org).ToList
Let AllCatNames = (From cat In CatAList Select cat.Name Distinct).Union(From cat In CatBList Select cat.Name Distinct)
Let BothCats = (From cat In AllCatNames
From A In CatAList.Where(Function(CatA) CatA.Name = cat).DefaultIfEmpty
From B In CatBList.Where(Function(CatB) CatB.Name = cat).DefaultIfEmpty)
Select org, BothCats
End Sub