CONVERTER UM RESULTADO DE LINQ TO SQL EM DATASET
Pessoal
Alguem tem ideia de como faço para pegar um resultado de linq to SQL e transforma-lo em um dataset?
Att.
Angelo
Alguem tem ideia de como faço para pegar um resultado de linq to SQL e transforma-lo em um dataset?
Att.
Angelo
Você precisa fazer [Ô]shallow copy[Ô] como infelizmente o VB não possui método nativo para isso como o C#, montei a classe genérica ObjectShredder usando Reflection e criei Extensions no módulo DataSetLinqOperators, logo abaixo posto estes códigos, para usar é algo como :
A Classe usa Generic e importa Reflection (aconselho estudar essas técnicas que considero essenciais para um bom programador.
[ô] Carregar em um novo DataTable
Dim query1 = From i In tabela_obj Where i.Preco > 9.99 Order By i.Nome
Dim table1 As DataTable = query1.CopyToDataTable()
[ô] Carregar em DataTable existente
Dim table2 As New DataTable()
table2.Columns.Add([Ô]Preco[Ô], GetType(Integer))
table2.Columns.Add([Ô]Nome[Ô], GetType(String))
Dim query2 = From i In tabela_obj Where i.Preco > 9.99 Order By i.PrecoNew
query2.CopyToDataTable(table2, LoadOption.PreserveChanges)
A Classe usa Generic e importa Reflection (aconselho estudar essas técnicas que considero essenciais para um bom programador.
Imports System.Reflection
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()
_ordinalMap = New Dictionary(Of String, Integer)()
End Sub
Public Function Shred(source As IEnumerable(Of T), table As DataTable, 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), options.Value)
Else
table.LoadDataRow(ShredObject(table, e.Current), True)
End If
End While
End Using
table.EndLoadData()
Return table
End Function
Public Function ShredPrimitive(source As IEnumerable(Of T), table As DataTable, 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, options.Value)
Else
table.LoadDataRow(values, True)
End If
End While
End Using
table.EndLoadData()
Return table
End Function
Public Function ExtendTable(table As DataTable, 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
For Each p As PropertyInfo In type.GetProperties()
If Not _ordinalMap.ContainsKey(p.Name) Then
Dim dc As DataColumn = If(table.Columns.Contains(p.Name), table.Columns(p.Name), table.Columns.Add(p.Name, p.PropertyType))
_ordinalMap.Add(p.Name, dc.Ordinal)
End If
Next
Return table
End Function
Public Function ShredObject(table As DataTable, instance As T) As Object()
Dim fi As FieldInfo() = _fi
Dim pi As PropertyInfo() = _pi
If instance.[GetType]() IsNot GetType(T) Then
ExtendTable(table, instance.[GetType]())
fi = instance.[GetType]().GetFields()
pi = instance.[GetType]().GetProperties()
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
Public Module DataSetLinqOperators
<System.Runtime.CompilerServices.Extension> _
Public Function CopyToDataTable(Of T)(source As IEnumerable(Of T)) As DataTable
Return New ObjectShredder(Of T)().Shred(source, Nothing, Nothing)
End Function
<System.Runtime.CompilerServices.Extension> _
Public Function CopyToDataTable(Of T)(source As IEnumerable(Of T), table As DataTable, options As System.Nullable(Of LoadOption)) As DataTable
Return New ObjectShredder(Of T)().Shred(source, table, options)
End Function
End Module
Bom tentei com o copydatable no visual studio 2010, so que ocorre o seguinte erro:
[ô]copydatatable[ô] não é membro de system.link.iquerable
O que pode ser isso?
Att.
O erro ocorre por que copydatatable é para linq2object e não para linq2sql, você só pode usa métodos que podem ser convertidos para comandos SQL.
Tópico encerrado , respostas não são mais permitidas