?
Solved

How do I create a data relation on generic lists?

Posted on 2009-12-16
6
Medium Priority
?
780 Views
Last Modified: 2013-11-25
I have two generic lists that I wish to perform a data relation on similar to what you can do with data tables. One list is a list of parent objects, and the other is a list of child objects. Is this possible, and if so, how can it be done? I will be binding to an Infragistics UlgraGrid.

Environment: XP OS using VS 2008 .NET v3.5
Dim lstParent As New List(Of ParentObject)
lstParent = GetParentList(obj) 
Dim lstChild As New List(Of ChildObject)
lstChild = GetChildList(obj) 
Dim MyRelation as new DataRelation()

Open in new window

0
Comment
Question by:CADOIM
  • 3
  • 3
6 Comments
 
LVL 15

Expert Comment

by:x77
ID: 26066629
Your informaction is difuse.
I know than you can create a datarelation Datatable.Colummn -  RelatatedTable.(keycolumn)
also with Linq you can create a Lookup from a list to other enumerable (Net 3.5).
but you neeed more explicit on requiriments.

Sorry on gramatic, I`m spanish.
Dataview only supports information on table columns,  lookup relate elementens on a colection on other.
Linq result can be a datasource, also a dataview or datatable can be a datasource.
I prefer datatable/datasource.
But  wat you is intend?
Datatable/dataview  has a lot of interfaces to use, BusinesObjects use Reflection to access public properties.

I has expoxed on previous questions how to Linq can become an choice to classic DataView.

I think Ilookup is the solution for you, bu it is a complex solution to explain with your exposition.
Ilookup is a HasTable that contains a key from primary colletion that contains many elements on secondary collection.
You need define a function to use with ToLookup of Linq.

        Public Shared Function GetSuc(ByVal c As CTE) As Integer
            Return c._Suc
        End Function
        LookupPred = Ctes.ToLookup(Of Int32)(AddressOf CTE.GetSuc)

Where Ctes is a Ienumerable of Cte and Cte.GetSuc return a Int32.

Code Result:
True
2
AValue1
AValue2


Module Module1
    Sub Main()
        Dim list2 As New List(Of datos)
        list2.Add(New datos("a", "AValue1"))
        list2.Add(New datos("a", "AValue2"))
        list2.Add(New datos("b", "bValue1"))
        Dim MyLookup = (From Item In list2 Select Item).ToLookup(Of String)(AddressOf datos.getKey)
        Debug.Print(MyLookup.Contains("a").ToString)
        Debug.Print(MyLookup("a").Count.ToString)
        For Each dato In MyLookup("a")
            Debug.Print(dato.value)
        Next
    End Sub
End Module
Public Class datos
    Public Key As String
    Public value As String
    Public Sub New(ByVal key As String, ByVal value As String)
        Me.Key = key
        Me.value = value
    End Sub
    Public Shared Function getKey(ByVal item As datos) As String
        Return item.Key
    End Function
End Class

Open in new window

0
 

Author Comment

by:CADOIM
ID: 26067002
x77,

Thank you for the quick reply. I really need to be able to pass in a list and have it do the conversion without having to explicitly write out each column. Also, we don't use Linq in our department to access the database.

Here is what I ended up doing: I don't know how it works, but somehow by sending the list into an XML serializer, it can spit it out as a dataset (mind you it has difficulty returning a datatable). I can pass in the lists I want into this function, return them as datatables, combine them all back into one dataset, and create the relation on the dataset. Don't know if there's a better way, but this way works for me.
0
 
LVL 15

Expert Comment

by:x77
ID: 26067559
I worked only with Xml DataSet/DataTables or Config Settings, do´nt use XmlDocument .
It´s easy, you create a  DataTable and fill it reading each row (Element) from Xml Document.
Then bind DataTable to Infragistics UlgraGrid.

Create DataTable:
Dim MyTable as new DataTable
MyTable.Columns.add(new Datacolumn("ColumnName", GetType(ColumnType))
--- For each Column, Where ColumnType is String, Int32....
For Each Document Row:
    MyTable.Rows.Add(Data1,Data2.....)

To Work with XmlDocument :
http://support.microsoft.com/kb/301225
0
NEW Veeam Agent for Microsoft Windows

Backup and recover physical and cloud-based servers and workstations, as well as endpoint devices that belong to remote users. Avoid downtime and data loss quickly and easily for Windows-based physical or public cloud-based workloads!

 

Accepted Solution

by:
CADOIM earned 0 total points
ID: 26071567
My code must not have attached with my reply, let's try this again. Anyway, I didn't even have to manually add columns to my data table. The dataset can read the xml file and create its own columns. You then convert the data set to a data table for each list and combine all data tables into one data set to do the filtering on.

Here is the link for more information: http://codeasp.net/blogs/shaitender/microsoft-net/168/convert-generic-list-to-dataset

Not sure how to award points, since I used my own solution. Hopefully this will help someone else out though.
Public Function ConvListToDataTable(ByVal lstValue As List(Of Object)) As DataTable
Dim sb As New StringBuilder()
Dim xmlSerializer As New XmlSerializer(GetType(List(Of Object)))
Dim sw As New StringWriter(sb)
xmlSerializer.Serialize(sw, lstValue)
Dim stream As New StringReader(sb.ToString())
Dim dSet As New DataSet
dSet.ReadXml(stream)
Dim dt As New DataTable
dt = dSet.Tables(0)
Return dt
End Function

Open in new window

0
 
LVL 15

Expert Comment

by:x77
ID: 26086661
Microsoft Serialization is a typed model, if you serialize an object then you deserialize that object not other.
This is enforced, you can´nt use DataSet.ReadXml from a stream that was created from serialization on an no dataset object.

You need create a function that returns a DataRow from each object instance in the list.
Then add each row to DataTable.

Note, for fast DataTable creation, assign MyDataTable.MinimumCapacity = MyList.Count before add first row.
Also use    BeginLoadData()   and  EndLoadData() to avoid raise events on each added DataRow.
0
 

Author Comment

by:CADOIM
ID: 26105809
Actually, you can. The code I posted above works, so evidently you can use DataSet.ReadXml to read a stream created from serialization on a list object. Don't ask me how it works, it just does 8)
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Enums (shorthand for ‘enumerations’) are not often used by programmers but they can be quite valuable when they are.  What are they? An Enum is just a type of variable like a string or an Integer, but in this case one that you create that contains…
Simulator games are perfect for generating sample realistic data streams, especially for learning data analysis. It is even useful for demoing offerings such as Azure stream analytics, PowerBI etc.
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…

850 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question