Versión Copiada del tfs
This commit is contained in:
150
Extensiones/IEnumerable.vb
Normal file
150
Extensiones/IEnumerable.vb
Normal file
@@ -0,0 +1,150 @@
|
||||
Imports System.Runtime.CompilerServices
|
||||
Imports System.Reflection
|
||||
Imports System.Data
|
||||
|
||||
Namespace Extensiones
|
||||
Public Module IEnumerableExtensions
|
||||
|
||||
<Extension()>
|
||||
Public Function CopyToDataTable(Of T)(ByVal source As IEnumerable(Of T)) As DataTable
|
||||
Return New ObjectShredder(Of T)().Shred(source, Nothing, Nothing)
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Public Function CopyToDataTable(Of T)(ByVal source As IEnumerable(Of T), ByVal table As DataTable, ByVal options As LoadOption?) As DataTable
|
||||
Return New ObjectShredder(Of T)().Shred(source, table, options)
|
||||
End Function
|
||||
|
||||
End Module
|
||||
End Namespace
|
||||
|
||||
Public Class ObjectShredder(Of T)
|
||||
Private _fi As FieldInfo()
|
||||
Private _pi As PropertyInfo()
|
||||
Private _ordinalMap As Dictionary(Of String, Integer)
|
||||
Private _type As Type
|
||||
|
||||
Public Sub New()
|
||||
_type = GetType(T)
|
||||
_fi = _type.GetFields()
|
||||
_pi = _type.GetProperties.Where(Function(x) Not (x.PropertyType.Name.Contains("EntityReference") OrElse x.PropertyType.Name.Contains("EntityCollection") OrElse x.PropertyType.Name.Contains("EntityState") OrElse x.PropertyType.Name.Contains("EntityKey") OrElse x.PropertyType.BaseType.Name = "EntityObject")).ToArray
|
||||
_ordinalMap = New Dictionary(Of String, Integer)()
|
||||
End Sub
|
||||
|
||||
Public Function Shred(ByVal source As IEnumerable(Of T), ByVal table As DataTable, ByVal options As LoadOption?) As DataTable
|
||||
If GetType(T).IsPrimitive Then
|
||||
Return ShredPrimitive(source, table, options)
|
||||
End If
|
||||
|
||||
If table Is Nothing Then
|
||||
table = New DataTable(GetType(T).Name)
|
||||
End If
|
||||
|
||||
table = ExtendTable(table, GetType(T))
|
||||
table.BeginLoadData()
|
||||
|
||||
Using e As IEnumerator(Of T) = source.GetEnumerator()
|
||||
|
||||
While e.MoveNext()
|
||||
|
||||
If options IsNot Nothing Then
|
||||
table.LoadDataRow(ShredObject(table, e.Current), CType(options, LoadOption))
|
||||
Else
|
||||
table.LoadDataRow(ShredObject(table, e.Current), True)
|
||||
End If
|
||||
End While
|
||||
End Using
|
||||
|
||||
table.EndLoadData()
|
||||
Return table
|
||||
End Function
|
||||
|
||||
Public Function ShredPrimitive(ByVal source As IEnumerable(Of T), ByVal table As DataTable, ByVal options As LoadOption?) As DataTable
|
||||
If table Is Nothing Then
|
||||
table = New DataTable(GetType(T).Name)
|
||||
End If
|
||||
|
||||
If Not table.Columns.Contains("Value") Then
|
||||
table.Columns.Add("Value", GetType(T))
|
||||
End If
|
||||
|
||||
table.BeginLoadData()
|
||||
|
||||
Using e As IEnumerator(Of T) = source.GetEnumerator()
|
||||
Dim values As Object() = New Object(table.Columns.Count - 1) {}
|
||||
|
||||
While e.MoveNext()
|
||||
values(table.Columns("Value").Ordinal) = e.Current
|
||||
|
||||
If options IsNot Nothing Then
|
||||
table.LoadDataRow(values, CType(options, LoadOption))
|
||||
Else
|
||||
table.LoadDataRow(values, True)
|
||||
End If
|
||||
End While
|
||||
End Using
|
||||
|
||||
table.EndLoadData()
|
||||
Return table
|
||||
End Function
|
||||
|
||||
Public Function ExtendTable(ByVal table As DataTable, ByVal type As Type) As DataTable
|
||||
For Each f As FieldInfo In type.GetFields()
|
||||
|
||||
If Not _ordinalMap.ContainsKey(f.Name) Then
|
||||
Dim dc As DataColumn = If(table.Columns.Contains(f.Name), table.Columns(f.Name), table.Columns.Add(f.Name, f.FieldType))
|
||||
_ordinalMap.Add(f.Name, dc.Ordinal)
|
||||
End If
|
||||
Next
|
||||
Dim Propiedades = type.GetProperties.Where(Function(x) Not (x.PropertyType.Name.Contains("EntityReference") OrElse x.PropertyType.Name.Contains("EntityCollection") OrElse x.PropertyType.Name.Contains("EntityState") OrElse x.PropertyType.Name.Contains("EntityKey") OrElse x.PropertyType.BaseType.Name = "EntityObject"))
|
||||
|
||||
For Each p As PropertyInfo In Propiedades
|
||||
|
||||
If Not _ordinalMap.ContainsKey(p.Name) Then
|
||||
Dim propiedad = p.PropertyType
|
||||
If propiedad Is GetType(Integer?) Then
|
||||
propiedad = GetType(Integer)
|
||||
ElseIf propiedad Is GetType(Double?) Then
|
||||
propiedad = GetType(Double)
|
||||
ElseIf propiedad Is GetType(Long?) Then
|
||||
propiedad = GetType(Long)
|
||||
ElseIf propiedad Is GetType(Boolean?) Then
|
||||
propiedad = GetType(Boolean)
|
||||
ElseIf propiedad Is GetType(DateTime?) Then
|
||||
propiedad = GetType(DateTime)
|
||||
ElseIf propiedad Is GetType(Date?) Then
|
||||
propiedad = GetType(Date)
|
||||
End If
|
||||
Dim dc As DataColumn = If(table.Columns.Contains(p.Name), table.Columns(p.Name), table.Columns.Add(p.Name, propiedad))
|
||||
_ordinalMap.Add(p.Name, dc.Ordinal)
|
||||
End If
|
||||
Next
|
||||
|
||||
Return table
|
||||
End Function
|
||||
|
||||
Public Function ShredObject(ByVal table As DataTable, ByVal instance As T) As Object()
|
||||
Dim fi As FieldInfo() = _fi
|
||||
Dim pi As PropertyInfo() = _pi
|
||||
|
||||
If instance.[GetType]() <> GetType(T) Then
|
||||
ExtendTable(table, instance.[GetType]())
|
||||
fi = instance.[GetType]().GetFields()
|
||||
pi = instance.[GetType]().GetProperties.Where(Function(x) Not (x.PropertyType.Name.Contains("EntityReference") OrElse x.PropertyType.Name.Contains("EntityCollection") OrElse x.PropertyType.Name.Contains("EntityState") OrElse x.PropertyType.Name.Contains("EntityKey") OrElse x.PropertyType.BaseType.Name = "EntityObject")).ToArray
|
||||
End If
|
||||
|
||||
Dim values As Object() = New Object(table.Columns.Count - 1) {}
|
||||
|
||||
For Each f As FieldInfo In fi
|
||||
values(_ordinalMap(f.Name)) = f.GetValue(instance)
|
||||
Next
|
||||
|
||||
For Each p As PropertyInfo In pi
|
||||
values(_ordinalMap(p.Name)) = p.GetValue(instance, Nothing)
|
||||
Next
|
||||
|
||||
Return values
|
||||
End Function
|
||||
End Class
|
||||
|
||||
|
||||
Reference in New Issue
Block a user