LINQ Group by с несколькими свойствами в VB.Net
Я потратил много времени на эту проблему. Я могу сделать простую группу по запросам LINQ (по одному свойству), но для нескольких полей я немного застрял... Вот пример LINQPad того, что я хочу сделать:
dim lFinal={new with {.Year=2010, .Month=6, .Value1=0, .Value2=0},
new with {.Year=2010, .Month=6, .Value1=2, .Value2=1},
new with {.Year=2010, .Month=7, .Value1=3, .Value2=4},
new with {.Year=2010, .Month=8, .Value1=0, .Value2=1},
new with {.Year=2011, .Month=1, .Value1=2, .Value2=2},
new with {.Year=2011, .Month=1, .Value1=0, .Value2=0}}
Dim lFinal2 = From el In lFinal
Group el By Key = new with {el.Year,el.Month}
Into Group
Select New With {.Year = Key.Year, .Month=Key.Month, .Value1 = Group.Sum(Function(x) x.Value1), .Value2 = Group.Sum(Function(x) x.Value2)}
lFinal.Dump()
lFinal2.Dump()
список lFinal имеет 6 элементов, я хочу, чтобы lFinal2 имел 4 элемента: 2010-6 и 2011-1 должны группироваться.
спасибо заранее.
3 ответов
не 100% уверен, но group by, вероятно, использует реализацию Equals () и/или GetHashCode, поэтому, когда вы делаете неявное создание:
= Group el By Key = new with {el.Year,el.Month}
неявный объект не знает, как проверять год и месяц (только потому, что он имеет свойства, не означает, что он проверяет их при сравнении с другими объектами).
поэтому вам, вероятно, нужно будет сделать что-то еще вроде этого:
= Group el By Key = new CustomKey() { Year = el.Year, Month = el.Month };
public class CustomKey{
int Year { get; set; }
int Month { get; set; }
public override bool Equals(obj A) {
var key (CustomKey)A;
return key.Year == this.Year && key.Month == this.Month;
}
}
сделайте свойства анонимного типа неизменяемыми с помощью Key
ключевое слово, а затем они будут использоваться для сравнения
Dim lFinal2 = From el In lFinal
Group el By Key = new with {key el.Year, key el.Month}
Into Group
Select New With {
.Year = Key.Year,
.Month = Key.Month,
.Value1 = Group.Sum(Function(x) x.Value1),
.Value2 = Group.Sum(Function(x) x.Value2)
}
спасибо ! Но я заметил, что мне нужно также написать функцию GetHashCode, чтобы она работала. Я предоставляю VB.Net перевод финального класса + LINQ GroupBy:
класс :
Public Class YearMonth
Implements IEquatable(Of YearMonth)
Public Property Year As Integer
Public Property Month As Integer
Public Function Equals1(other As YearMonth) As Boolean Implements System.IEquatable(Of YearMonth).Equals
Return other.Year = Me.Year And other.Month = Me.Month
End Function
Public Overrides Function GetHashCode() As Integer
Return Me.Year * 1000 + Me.Month * 100
End Function
End Class
и запрос LINQ :
Dim lFinal2 = From el In lFinal
Group el By Key = New YearMonth With {.Year = el.Year, .Month = el.Month}
Into Group
Select New ItemsByDates With {.Year = Key.Year,
.Month = Key.Month,
.Value1 = Group.Sum(Function(x) x.Value1),
.Value2 = Group.Sum(Function(x) x.Value2)}