I have,
A list, MyList, of objects with fields:
string A;
string B;
Conceptually, this is similar to a two column SQL Table with columns A, B.
I'm trying to create a linq expression that would produce the three column result set of this T-SQL on such a conceptual table:
SELECT A, B, COUNT(B)
FROM T1
GROUP BY A, B
That is, if I had a table such as:
A B
----------
x g
x g
x g
x s
y g
y g
I would expect:
A B COUNT(B)
-------------------------
x g 3
x s 1
y g 2
My best efforts were this:
var result = from MyObjs in MyList
group MyObjs by new { MyObjs.A, MyObjs.B } into g
select new { g.Key.A, g.Key.B, g.Key.B.Count() }
But the count appears to return the total number of B's not the number of B's per multiple column group. How can this be fixed?
Try this.... (off the top of my head)
var result = from MyObjs in MyList
group MyObjs by new { MyObjs.A, MyObjs.B } into g
select new { g.Key.A, g.Key.B, MyCount = g.Count() }
Or if you prefer...
var result = MyList.GroupBy(x => new {x.A, x.B})
.Select(g => new {g.Key.A, g.Key.B, MyCount = g.Count()});
Related
I'm writing VB Code and I see a question below
There are three positive integers A, B, C
If A is greater than B, C is equal to A+B
If A is less than or equal to B, then C is equal to A-B.
Please use IF...Then and Select/Switch Case to write a program, both of which are used in this program, and additional variables can be added by yourself.
I would like to ask how to write this question, as far as I know, the answer just need only IF Then or Select Case can be realized?
Dim A As Double = 3
Dim B As Double = 2
Dim C As Double = 1
Dim D As Double = 0
D = A - B
Select Case D
Case D > 0
C = A + B
Case D < 0
C = A - B
End Select
If D > 0 Then
C = A + B
ElseIf D < 0 Then
C = A - B
End If
In the real world you wouldn't need to use both an If/Then statement and a Select/Case statement. Since this appears to be homework, I believe the exercise is to see if you can use both conditional check.
I would setup two functions that accept two arguments (a and b) that return the value of c. In your first function use an If/Then and in your second function use a Select/Case.
E.g.
Private Function IfThenOption(a As Integer, b As Integer) As Integer
Dim c As Integer
If (a > b) Then
c = a + b
ElseIf (a < b) Then
c = a - b
Else
c = a
End If
Return c
End Function
Private Function SelectCaseOption(a As Integer, b As Integer) As Integer
Dim c As Integer
Select Case True
Case a > b
c = a + b
Case a < b
c = a - b
Case Else
c = a
End Select
Return c
End Function
Example: https://dotnetfiddle.net/kwcyWc
I want to remove duplicate elements of string1 from string 2 and then output new string. My code works only if duplicate elements are in sequential order.
I want to work it any order of elements. Please advise.
Current Code:
set str1 "a 1 b 2 c 3 X Y Z"
set str2 "a 1 b 2 c 3 P Q R"
set results {}
set results [lmap a_elem $str1 b_elem $str2 {
if {$a_elem != $b_elem} {string cat $b_elem} else continue
}]
puts $results
Output of the following code :
P Q R
However, if
set str1 "a 1 b 2 c 3 X Y Z"
set str2 "P a 2 1 R c Q 3 b"
then Output will be : P a 2 1 R c Q 3 b
Basically same as str2 without the duplicate elimnation.
If you want to output those elements of the list in str2 that are nowhere in str1, you should first build a dictionary of the elements of str1 so that you can use efficient lookup (dicts are internally hash tables). You are strongly recommended to use a procedure for this as it makes the implementation rather more efficient.
proc removeItems {str1 str2} {
foreach item $str1 {
dict set items $item ""; # Value unimportant
}
lmap item $str2 {
if {[dict exists $items $item]} continue
string cat $item
}
}
puts [removeItems "a 1 b 2 c 3 X Y Z" "P a 2 1 R c Q 3 b"]
# P R Q
The code naturally assumes that the order of str2 is important.
If performance is not important, you can use the more straight forward:
set results [lmap elem $str2 {
if {$elem ni $str1} {string cat $elem} else continue
}]
Yesterday I asked this question on stackoverflow. Today I realize that if I do a GROUP BY I also need to create a new type of object.
Let's say I have some data that looks like this:
var1 var2 var3 qty
1 a 1a 50
1 a 1a 25
2 b 2b 10
2 b 2b 15
2 b 2b 10
3 a 3a 25
Here is my working LinQ query
From j In MyTable
Where j.var1 = "xxx"
Group j By Key = New With {Key .var1 = j.var1, Key .var2= j.var2, Key .var3 = j.var3} Into Group
Select New With {.var1 = Key.var1, .var2 = Key.var2, .var3 = Key.var3, .qty = Group.Sum(Function(x) x.qty)}
Actually I use Entity Framework and the code look more like this
Dim foo = (From j In dbContext.MyTable
Where j.var1 = anotherVariable
Group j By Key = New With {Key .var1 = j.var1, Key .var2= j.var2, Key .var3 = j.var3} Into Group
Select New With {.var1 = Key.var1, .var2 = Key.var2, .var3 = Key.var3, .quantity = Group.Sum(Function(x) x.Qty)}).ToArray()
foo is a new type that doesn't exist in my generated Entities. But I have an entity generated by my entity framework that can contains these. It's MyTable itself. I use a GROUP BY only to sum a column of MyTable. I query a MyTable entities and I can put the result in a MyTable entity too.
My question are
1) Can I write something like this
Dim foo = (From j In dbContext.MyTable
Where j.var1 = anotherVariable
Group j By Key = New With {Key .var1 = j.var1, Key .var2= j.var2, Key .var3 = j.var3} Into Group
Select New MyTable With {.var1 = Key.var1, .var2 = Key.var2, .var3 = Key.var3, .qty = Group.Sum(Function(x) x.qty)}).ToArray()
In this case do I need to explicitely write all the mappings ?
2) Should I change my mind. Do a simpler query without GROUP BY and try to group and sum in a VB.NET loop (For Each). Or two queries ? On to get all MyTable with a WHERE clause and another to group ?
Dim foo = dbContext.MyTable.Where(Function(p As MyTable) p.var1 = anotherVariable).ToArray()
For Each bar In foo
'Code to group and sum or another query
Next
You won't be able to instantiate MyTable in an LINQ to Entities query but you can simply enumerate the results of the projection with ToArray and then construct the entities with another Select call.
I make sales and procurement system and when I work a query, or search the invoice number, the results appear in palm leaves View, but appears only in a row while the bill by no more than one row
And this was used by code
i.m used vb.net and database sql and b yway linq to sql
Try
Dim data = (From d In DBVariable.Data.masterfatoras
From f In DBVariable.Data.fatoras
From na In DBVariable.Data.asnafs
From sup In DBVariable.Data.suppliers
Where d.ID = f.mid Where d.num.Contains(txt)
Select d, f, na, sup).FirstOrDefault
TextBoxX1.Text = data.d.num
nammord.Text = (From supp In DBVariable.Data.suppliers Where data.d.idmord = supp.ID Select supp.Name).Single()
txtmord.Text = (From supp In DBVariable.Data.suppliers Where data.d.idmord = supp.ID Select supp.Code).Single()
adrmord.Text = (From supp In DBVariable.Data.suppliers Where data.d.idmord = supp.ID Select supp.Address).Single()
nodaf.Text = data.d.nodfa
' ''نفاصيل الفاتورة
For p As Integer = 0 To gridshraa.Rows.Count - 1
gridshraa.Rows(p).Cells(2).Value = (From asna In DBVariable.Data.asnafs Where data.f.idname = asna.ID Select asna.Name).Single()
gridshraa.Rows(p).Cells(1).Value = (From asna In DBVariable.Data.asnafs Where data.f.idname = asna.ID Select asna.code).Single()
gridshraa.Rows(p).Cells(3).Value = (From asna In DBVariable.Data.asnafs Where data.f.idname = asna.ID Select asna.unit).Single()
gridshraa.Rows(p).Cells(4).Value = data.f.qty
gridshraa.Rows(p).Cells(5).Value = data.f.price
gridshraa.Rows(p).Cells(6).Value = data.f.totprice
Next
Catch
End Try
i have the following vb.net LINQ Query
Dim q = From row In dx.AsEnumerable
Group row By G = New With {.Cat = row.Field(Of Integer)("catalogid")}.Cat,
New With {.Backorder = row.Field(Of Integer)("backorder")}.Backorder Into pg = Group
Select New With
{
.Cat = pg.Cat,
.Backorder = pg.Sum(Function(x) x.Backorder)
}
i have this datatable called dx
catalogid backorder
1 5
1 10
2 1
2 5
i want to Sum backorder column where catalogid is the same so the result is the following
catalogid backorder
1 15
2 6
in the Select new with part, what is wrong?
Try following...
var result = dx.AsEnumerable()
.GroupBy(row => row.Field<int>("catalogid"))
.Select(group => group.Sum(item => item.Field<int> ("backorder")).CopyToDataTable();
or
var result= from s in dx.AsEnumerable()
group s by s.Field<int>("catalogid") into grp
select new {
CatalogId= grp.Key,
Back Order = grp.Sum(r => r.Field<int>("backorder"))
};
DataTable datatbl = result.CopyToDataTable();