Answered by:
Sum object properties by its attribute using LINQ from multiple list

Question
-
Hallo I would like to write a LINQ query to sum object properties based on their attribute .
I have Datagridview like below. I want to loop through Datagridview Category column and write a sum of weights from two bindinglists.
Public Class Category1 <Category("WeightVegitables")> _ Public Property Tomatto() As Integer <Category("WeightFruits")> _ Public Property Apple() As Integer <Category("WeightFruits")> _ Public Property Banana() As Integer <Category("WeightMeats")> __ Public Property Pork() As Integer <Category("WeightMeats")> __ Public Property Fish() As Integer End Class Public Class Categories1 Inherits System.ComponentModel.BindingList(Of Category1) End Class Public Class Category2 <Category("WeightVegitables")> _ Public Property Brinjal() As Integer <Category("WeightFruits")> _ Public Property Orange() As Integer <Category("WeightMeats")> __ Public Property Chicken() As Integer End Class Public Class Categories2 Inherits System.ComponentModel.BindingList(Of Category2) End Class
Or is there any alternative method to the example but without attributes?
Can i have more than 1 attribute to a property?
Thanks
- Edited by Shan1986 Tuesday, November 24, 2020 8:22 PM
Tuesday, November 24, 2020 12:51 PM
Answers
-
Hi Shan1986,
Thank you for posting here.
I make a test based on your description, and here's my custom attribute 'Category'.
<System.AttributeUsage(System.AttributeTargets.Property)> Public Class Category Inherits System.Attribute Public weightCategory As String Sub New(ByVal category As String) weightCategory = category End Sub End Class
The following example calculates the sum of ‘WeightVegitables’, ‘WeightFruits’ and ‘WeightMeats’ from a given ‘Categories1’.
Private WeightVegitablesCount As Integer Private WeightFruitsCount As Integer Private WeightMeatsCount As Integer Private lst As Categories1 = New Categories1() Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load lst.Add(New Category1() With { .Tomatto = 10, .Apple = 20, .Banana = 30, .Fish = 40, .Pork = 50 }) lst.Add(New Category1() With { .Tomatto = 11, .Apple = 22, .Banana = 33, .Fish = 44, .Pork = 55 }) lst.Add(New Category1() With { .Tomatto = 12, .Apple = 23, .Banana = 32, .Fish = 46, .Pork = 57 }) End Sub Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click For Each prop In GetType(Category1).GetProperties() Dim ca = CType(prop.GetCustomAttributes(GetType(Category), False).FirstOrDefault(), Category) Dim value As Integer = lst.Sum(Function(x) CInt((x.GetType().GetProperty(prop.Name).GetValue(x)))) Select Case ca.weightCategory Case "WeightVegitables" WeightVegitablesCount += value Case "WeightFruits" WeightFruitsCount += value Case "WeightMeats" WeightMeatsCount += value End Select Next MessageBox.Show($"WeightVegitables: {WeightVegitablesCount} WeightFruits:{WeightFruitsCount} WeightMeats:{WeightMeatsCount}") End Sub
The above code also applies to 'Categories2'.
Hope it could be helpful.
Best Regards,
Xingyu Zhao
Visual Basic and CLR forum will be migrating to a new home on Microsoft Q&A! (VB.NET and CLR) We invite you to post new questions in the new home on Microsoft Q&A ! For more information, please refer to the sticky post(VB.NET and CLR).
- Edited by Xingyu ZhaoMicrosoft contingent staff Wednesday, November 25, 2020 6:54 AM
- Marked as answer by Shan1986 Thursday, November 26, 2020 7:21 AM
Wednesday, November 25, 2020 6:52 AM
All replies
-
Hi Shan1986,
Thank you for posting here.
I make a test based on your description, and here's my custom attribute 'Category'.
<System.AttributeUsage(System.AttributeTargets.Property)> Public Class Category Inherits System.Attribute Public weightCategory As String Sub New(ByVal category As String) weightCategory = category End Sub End Class
The following example calculates the sum of ‘WeightVegitables’, ‘WeightFruits’ and ‘WeightMeats’ from a given ‘Categories1’.
Private WeightVegitablesCount As Integer Private WeightFruitsCount As Integer Private WeightMeatsCount As Integer Private lst As Categories1 = New Categories1() Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load lst.Add(New Category1() With { .Tomatto = 10, .Apple = 20, .Banana = 30, .Fish = 40, .Pork = 50 }) lst.Add(New Category1() With { .Tomatto = 11, .Apple = 22, .Banana = 33, .Fish = 44, .Pork = 55 }) lst.Add(New Category1() With { .Tomatto = 12, .Apple = 23, .Banana = 32, .Fish = 46, .Pork = 57 }) End Sub Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click For Each prop In GetType(Category1).GetProperties() Dim ca = CType(prop.GetCustomAttributes(GetType(Category), False).FirstOrDefault(), Category) Dim value As Integer = lst.Sum(Function(x) CInt((x.GetType().GetProperty(prop.Name).GetValue(x)))) Select Case ca.weightCategory Case "WeightVegitables" WeightVegitablesCount += value Case "WeightFruits" WeightFruitsCount += value Case "WeightMeats" WeightMeatsCount += value End Select Next MessageBox.Show($"WeightVegitables: {WeightVegitablesCount} WeightFruits:{WeightFruitsCount} WeightMeats:{WeightMeatsCount}") End Sub
The above code also applies to 'Categories2'.
Hope it could be helpful.
Best Regards,
Xingyu Zhao
Visual Basic and CLR forum will be migrating to a new home on Microsoft Q&A! (VB.NET and CLR) We invite you to post new questions in the new home on Microsoft Q&A ! For more information, please refer to the sticky post(VB.NET and CLR).
- Edited by Xingyu ZhaoMicrosoft contingent staff Wednesday, November 25, 2020 6:54 AM
- Marked as answer by Shan1986 Thursday, November 26, 2020 7:21 AM
Wednesday, November 25, 2020 6:52 AM -
Hallo Xingyu. Thanks for the answer. I get error when i run it one this line ca was nothing and
"Select Case ca.weightCategory "
System.NullReferenceException: 'Object reference not set to an instance of an object.'
Thanks.
Wednesday, November 25, 2020 9:31 AM -
Hi,
Did you use the custom 'Category' I provided to make the test?
I can get the correct test result.
Best Regards,
Xingyu Zhao
Visual Basic and CLR forum will be migrating to a new home on Microsoft Q&A! (VB.NET and CLR) We invite you to post new questions in the new home on Microsoft Q&A ! For more information, please refer to the sticky post(VB.NET and CLR).
Thursday, November 26, 2020 1:37 AM -
Thanks Xingyu. It worked my mistake.Thursday, November 26, 2020 7:22 AM