问题
I have a function which is supposed to return an array of class type.
So from database I picked data and filled datatable. Now from datatable I am picking columns value and assigning to the properties of the class. But problem is that what I am doing will assign a single record only but I want to fill the class type array with multiple record.
My code:
Private Sub BindGridInfoFunctionalLocation()
Dim v_ObjDs As New DataSet
Try
v_ObjDs = v_ObjBREngine.FetchSqlDS("select FunctionalLocation as 'TagNo', EquipmentDescription as 'TagDescription', Area as 'ParentHeirarchy', EqptType as 'TypeClass' from EngineeringData")
Dim dtTableFL As DataTable
dtTableFL.Columns.Add("TagNo", GetType(String))
dtTableFL.Columns.Add("TagDescription", GetType(String))
dtTableFL.Columns.Add("ParentHeirarchy", GetType(String))
dtTableFL.Columns.Add("Class", GetType(String))
dtTableFL = v_ObjDs.Tables(0)
Dim AssetsCls As New AssetsDto
'Dim AssetsClsArray As New AssetsDto()
If v_ObjDs.Tables(0).Rows.Count > 0 Then
'v_ObjDs.Tables(0).Rows.Add(v_ObjDs.Tables(0).NewRow())
For Each Item In dtTableFL.Rows
AssetsCls.ASSETTAG = Item("TagNo")
AssetsCls.ASSETDESC = Item("TagDescription")
AssetsCls.PARENTTAG = Item("ParentHeirarchy")
AssetsCls.ASSETTYPE = Item("TypeClass")
Next
gv_InfoFunctionalLocation.DataSource = v_ObjDs
gv_InfoFunctionalLocation.DataBind()
End If
Catch ex As Exception
Throw ex
End Try
End Sub
Note:
the return type and everything should be like this since I am interacting with the client's web service and it expects it this way only.
回答1:
In your example there is no array where each element of the table could be stored after the transform in an AssetsDto. Moreover, you need to change from Sub to Function if you want to return anything to the caller.
Another important change is relative to the data structure used to store the Dtos. Instead of using an array (you need to know the number of elements to effectively use it), I suggest to use a List(Of AssetsDto) where you can dynamically add elements without worrying about the size to the list.
' Declare as a Function that returns a List(Of AssetsDto)
Private Function BindGridInfoFunctionalLocation() as List(Of AssetsDto)
Dim v_ObjDs As New DataSet
' This is where we store each record transformed in an AssetsDto
Dim result as List(Of AssetsDto) = new List(Of AssetsDto)
Try
v_ObjDs = v_ObjBREngine.FetchSqlDS("select FunctionalLocation as 'TagNo', EquipmentDescription as 'TagDescription', Area as 'ParentHeirarchy', EqptType as 'TypeClass' from EngineeringData")
Dim dtTableFL As DataTable = v_ObjDs.Tables(0)
' Cycle to create the AssetsDto
For Each Item In dtTableFL.Rows
' IMPORTANT. At each loop create a new AssetsDto, otherwise you
' will just change the values of the same instance
Dim AssetsCls As AssetsDto = new AssetsDto()
AssetsCls.ASSETTAG = Item("TagNo")
AssetsCls.ASSETDESC = Item("TagDescription")
AssetsCls.PARENTTAG = Item("ParentHeirarchy")
AssetsCls.ASSETTYPE = Item("TypeClass")
' Add the instance to the list
result.Add(AssetsCls)
Next
gv_InfoFunctionalLocation.DataSource = v_ObjDs
gv_InfoFunctionalLocation.DataBind()
End If
' Return to caller the results
Return results
Catch ex As Exception
Throw ex
End Try
End Function
回答2:
This is only an indirect answer, but: ultimately, the thing you are trying to do is a solved problem, with lots of tools existing to do all the work for you. Since this is a simple scenario, "Dapper" would make this trivial. I'll give a C# example here, as my VB level is read-only:
List<AssetsDto> BindGridInfoFunctionalLocation()
{
// note: column aliases to match properties on AssetsDto
var results = connection.Query<AssetsDto>(@"
select FunctionalLocation as 'ASSETTAG',
EquipmentDescription as 'ASSETDESC',
Area as 'PARENTTAG',
EqptType as 'ASSETTYPE'
from EngineeringData").AsList();
gv_InfoFunctionalLocation.DataSource = results;
gv_InfoFunctionalLocation.DataBind()
return results;
}
来源:https://stackoverflow.com/questions/62148534/how-to-return-an-array-of-class-type-and-fill