This commit is contained in:
276
source/csla10/CSLA/ObjectAdapter.vb
Normal file
276
source/csla10/CSLA/ObjectAdapter.vb
Normal file
@@ -0,0 +1,276 @@
|
||||
Imports System.ComponentModel
|
||||
Imports System.Reflection
|
||||
|
||||
''' <summary>
|
||||
'''
|
||||
''' </summary>
|
||||
Namespace Data
|
||||
|
||||
''' <summary>
|
||||
''' An ObjectAdapter is used to convert data in an object
|
||||
''' or collection into a DataTable.
|
||||
''' </summary>
|
||||
Public Class ObjectAdapter
|
||||
|
||||
Private mColumns As New ArrayList
|
||||
|
||||
''' <summary>
|
||||
''' Fills the DataSet with data from an object or collection.
|
||||
''' </summary>
|
||||
''' <remarks>
|
||||
''' The name of the DataTable being filled is will be the class name of
|
||||
''' the object acting as the data source. The
|
||||
''' DataTable will be inserted if it doesn't already exist in the DataSet.
|
||||
''' </remarks>
|
||||
''' <param name="ds">A reference to the DataSet to be filled.</param>
|
||||
''' <param name="source">A reference to the object or collection acting as a data source.</param>
|
||||
Public Sub Fill(ByVal ds As DataSet, ByVal source As Object)
|
||||
|
||||
Dim className As String
|
||||
className = TypeName(source)
|
||||
|
||||
Fill(ds, className, source)
|
||||
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' Fills the DataSet with data from an object or collection.
|
||||
''' </summary>
|
||||
''' <remarks>
|
||||
''' The name of the DataTable being filled is specified as a parameter. The
|
||||
''' DataTable will be inserted if it doesn't already exist in the DataSet.
|
||||
''' </remarks>
|
||||
''' <param name="ds">A reference to the DataSet to be filled.</param>
|
||||
''' <param name="TableName"></param>
|
||||
''' <param name="source">A reference to the object or collection acting as a data source.</param>
|
||||
Public Sub Fill(ByVal ds As DataSet, _
|
||||
ByVal TableName As String, ByVal source As Object)
|
||||
|
||||
Dim dt As DataTable
|
||||
Dim exists As Boolean
|
||||
|
||||
dt = ds.Tables(TableName)
|
||||
exists = Not dt Is Nothing
|
||||
|
||||
If Not exists Then
|
||||
dt = New DataTable(TableName)
|
||||
End If
|
||||
|
||||
Fill(dt, source)
|
||||
|
||||
If Not exists Then
|
||||
ds.Tables.Add(dt)
|
||||
End If
|
||||
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' Fills a DataTable with data values from an object or collection.
|
||||
''' </summary>
|
||||
''' <param name="dt">A reference to the DataTable to be filled.</param>
|
||||
''' <param name="source">A reference to the object or collection acting as a data source.</param>
|
||||
Public Sub Fill(ByVal dt As DataTable, ByVal source As Object)
|
||||
|
||||
AutoDiscover(source)
|
||||
DataCopy(dt, source)
|
||||
|
||||
End Sub
|
||||
|
||||
#Region " Data Copy "
|
||||
|
||||
Private Sub DataCopy(ByVal dt As DataTable, ByVal source As Object)
|
||||
|
||||
If source Is Nothing Then Exit Sub
|
||||
If mColumns.Count < 1 Then Exit Sub
|
||||
|
||||
If TypeOf source Is IListSource Then
|
||||
DataCopyIList(dt, CType(source, IListSource).GetList)
|
||||
|
||||
ElseIf TypeOf source Is IList Then
|
||||
DataCopyIList(dt, CType(source, IList))
|
||||
|
||||
Else
|
||||
' they gave us a regular object - create a list
|
||||
Dim col As New ArrayList
|
||||
col.Add(source)
|
||||
DataCopyIList(dt, CType(col, IList))
|
||||
End If
|
||||
|
||||
End Sub
|
||||
|
||||
Private Sub DataCopyIList(ByVal dt As DataTable, ByVal ds As IList)
|
||||
|
||||
Dim index As Integer
|
||||
Dim column As String
|
||||
'Dim item As String
|
||||
|
||||
' create columns if needed
|
||||
For Each column In mColumns
|
||||
If Not dt.Columns.Contains(column) Then
|
||||
dt.Columns.Add(column)
|
||||
End If
|
||||
Next
|
||||
|
||||
' load the data into the control
|
||||
dt.BeginLoadData()
|
||||
For index = 0 To ds.Count - 1
|
||||
Dim dr As DataRow = dt.NewRow
|
||||
For Each column In mColumns
|
||||
Try
|
||||
dr(column) = GetField(ds(index), column)
|
||||
|
||||
Catch ex As Exception
|
||||
dr(column) = ex.Message
|
||||
End Try
|
||||
Next
|
||||
dt.Rows.Add(dr)
|
||||
Next
|
||||
dt.EndLoadData()
|
||||
|
||||
End Sub
|
||||
|
||||
#End Region
|
||||
|
||||
#Region " AutoDiscover "
|
||||
|
||||
Private Sub AutoDiscover(ByVal source As Object)
|
||||
|
||||
Dim innerSource As Object
|
||||
|
||||
If TypeOf source Is IListSource Then
|
||||
innerSource = CType(source, IListSource).GetList
|
||||
|
||||
Else
|
||||
innerSource = source
|
||||
End If
|
||||
|
||||
mColumns.Clear()
|
||||
|
||||
If TypeOf innerSource Is DataView Then
|
||||
ScanDataView(CType(innerSource, DataView))
|
||||
|
||||
ElseIf TypeOf innerSource Is IList Then
|
||||
ScanIList(CType(innerSource, IList))
|
||||
|
||||
Else
|
||||
' they gave us a regular object
|
||||
ScanObject(innerSource)
|
||||
|
||||
End If
|
||||
|
||||
End Sub
|
||||
|
||||
Private Sub ScanDataView(ByVal ds As DataView)
|
||||
|
||||
Dim field As Integer
|
||||
|
||||
For field = 0 To ds.Table.Columns.Count - 1
|
||||
mColumns.Add(ds.Table.Columns(field).ColumnName)
|
||||
Next
|
||||
|
||||
End Sub
|
||||
|
||||
Private Sub ScanIList(ByVal ds As IList)
|
||||
|
||||
If ds.Count > 0 Then
|
||||
' retrieve the first item from the list
|
||||
Dim obj As Object = ds.Item(0)
|
||||
|
||||
If TypeOf obj Is ValueType AndAlso obj.GetType.IsPrimitive Then
|
||||
' the value is a primitive value type
|
||||
mColumns.Add("Value")
|
||||
|
||||
ElseIf TypeOf obj Is String Then
|
||||
' the value is a simple string
|
||||
mColumns.Add("Text")
|
||||
|
||||
Else
|
||||
' we have a complex Structure or object
|
||||
ScanObject(obj)
|
||||
End If
|
||||
End If
|
||||
|
||||
End Sub
|
||||
|
||||
Private Sub ScanObject(ByVal Source As Object)
|
||||
|
||||
Dim SourceType As Type = Source.GetType
|
||||
Dim column As Integer
|
||||
|
||||
' retrieve a list of all public properties
|
||||
Dim props As PropertyInfo() = SourceType.GetProperties()
|
||||
If UBound(props) >= 0 Then
|
||||
For column = 0 To UBound(props)
|
||||
If props(column).CanRead Then
|
||||
mColumns.Add(props(column).Name)
|
||||
End If
|
||||
Next
|
||||
End If
|
||||
|
||||
' retrieve a list of all public fields
|
||||
Dim fields As FieldInfo() = SourceType.GetFields()
|
||||
If UBound(fields) >= 0 Then
|
||||
For column = 0 To UBound(fields)
|
||||
mColumns.Add(fields(column).Name)
|
||||
Next
|
||||
End If
|
||||
|
||||
End Sub
|
||||
|
||||
#End Region
|
||||
|
||||
#Region " GetField "
|
||||
|
||||
Private Function GetField(ByVal obj As Object, ByVal FieldName As String) As String
|
||||
|
||||
If TypeOf obj Is DataRowView Then
|
||||
' this is a DataRowView from a DataView
|
||||
Return CType(obj, DataRowView).Item(FieldName).ToString
|
||||
|
||||
ElseIf TypeOf obj Is ValueType AndAlso obj.GetType.IsPrimitive Then
|
||||
' this is a primitive value type
|
||||
Return obj.ToString
|
||||
|
||||
ElseIf TypeOf obj Is String Then
|
||||
' this is a simple string
|
||||
Return CStr(obj)
|
||||
|
||||
Else
|
||||
' this is an object or Structure
|
||||
Try
|
||||
Dim sourcetype As Type = obj.GetType
|
||||
|
||||
' see if the field is a property
|
||||
Dim prop As PropertyInfo = sourcetype.GetProperty(FieldName)
|
||||
|
||||
If prop Is Nothing OrElse Not prop.CanRead Then
|
||||
' no readable property of that name exists - check for a field
|
||||
Dim field As FieldInfo = sourcetype.GetField(FieldName)
|
||||
|
||||
If field Is Nothing Then
|
||||
' no field exists either, throw an exception
|
||||
Throw New System.Data.DataException( _
|
||||
"No such value exists: " & FieldName)
|
||||
|
||||
Else
|
||||
' got a field, return its value
|
||||
Return field.GetValue(obj).ToString
|
||||
End If
|
||||
|
||||
Else
|
||||
' found a property, return its value
|
||||
Return prop.GetValue(obj, Nothing).ToString
|
||||
End If
|
||||
|
||||
Catch ex As Exception
|
||||
Throw New System.Data.DataException( _
|
||||
"Error reading value: " & FieldName, ex)
|
||||
End Try
|
||||
End If
|
||||
End Function
|
||||
|
||||
#End Region
|
||||
|
||||
End Class
|
||||
|
||||
End Namespace
|
||||
Reference in New Issue
Block a user