Kleine Vorbemerkung: für den Code hier wird die AdventureWorks-Datenbank verwendet.
Die Idee ist folgende:
Da Du später sowieso Arrays brauchst, kannst Du auch gleich direkt Arrays aus der DB ziehen.Using ctx As New AdventureWorksDataContext
ctx.Log = Console.Out
Dim qry = From em In ctx.Employees _
Where em.BirthDate > DateTime.Parse("1.1.1971") _
Select New Object() {em.EmployeeID, em.BirthDate}
Dim result As List(Of Object()) = qry.ToList
End Using An dieser Stelle haben wir immer noch das Problem, die erwünschten Spalten noch nicht dynamisch hinzufügen zu können. Also erstellen wir ein Modul mit einer neuen Extension.
Imports System.Linq.Expressions
Module QueryExtensions
''' <summary>
''' Projiziert jedes Element einer Sequenz in eine Sequenz von Object-Arrays,
' wobei die
''' Reihenfolge der Werte in jedem Object-Array den in propertyOrFieldName
' angegebenen
''' Namen entspricht.
''' </summary>
''' <typeparam name="T">Der Typ der Elemente von qry.</typeparam>
''' <param name="qry">Eine Sequenz von zu projizierenden Werten.</param>
''' <param name="propertyOrFieldName">Eine Auflistung von Property- oder
' Feldnamen.</param>
<System.Runtime.CompilerServices.Extension()> _
Public Function ColumnSelect(Of T)(ByVal qry As IQueryable(Of T), ByVal _
ParamArray propertyOrFieldName As String()) As IQueryable(Of Object())
If qry Is Nothing Then
Throw New ArgumentNullException("qry")
End If
If propertyOrFieldName.Length = 0 Then
Throw New ArgumentException("Es muss mindestens ein Property- bzw. FieldName" & _
"angegeben werden", "propertyOrFieldName")
End If
Dim pxp As ParameterExpression = Expression.Parameter(GetType(T), "p")
Dim initializers As New List(Of Expression)
For Each memberName As String In propertyOrFieldName
Dim memXp As MemberExpression = Expression.PropertyOrField(pxp, memberName)
Dim quote As UnaryExpression = Expression.Quote(memXp)
initializers.Add(quote)
Next
Dim newArXp As NewArrayExpression = Expression.NewArrayInit(GetType(Object), _
initializers)
Dim lamba As LambdaExpression = Expression.Lambda(newArXp, pxp)
Dim typeArguments As Type() = {qry.ElementType, lamba.Body.Type}
Dim methodCallXp As MethodCallExpression = Expression.Call(GetType( _
Queryable), "Select", typeArguments, qry.Expression, lamba)
Dim retQry As IQueryable(Of Object()) = qry.Provider.CreateQuery(Of Object())( _
methodCallXp)
Return retQry
End Function
End Module Beispiel für eine Abfrage, die zwei Datenbankspalten abfragtUsing ctx As New AdventureWorksDataContext
ctx.Log = Console.Out
Dim qry = From em In ctx.Employees _
Where em.BirthDate > DateTime.Parse("1.1.1971") _
Select em
Dim result As List(Of Object()) = qry.ColumnSelect("EmployeeID", _
"BirthDate").Take(10).ToList
End Using Das gleiche mit nur einer SpalteUsing ctx As New AdventureWorksDataContext
ctx.Log = Console.Out
Dim qry = From em In ctx.Employees _
Where em.BirthDate > DateTime.Parse("1.1.1971") _
Select em
Dim result As List(Of Object()) = qry.ColumnSelect("EmployeeID").Take( _
10).ToList
End Using Beispiel mit Array als ParamterübergabeUsing ctx As New AdventureWorksDataContext
ctx.Log = Console.Out
Dim qry = From em In ctx.Employees _
Where em.BirthDate > DateTime.Parse("1.1.1971") _
Select em
Dim colNames As String() = {"EmployeeID", "BirthDate"}
Dim result As List(Of Object()) = qry.ColumnSelect(colNames).Take(10).ToList
End Using Statt Dim colNames As String() = {"EmployeeID", "BirthDate"} kannst Du natürlich jedes beliebige, dynamisch erstellte Array hernehmen.
Ciao D.
Beitrag wurde zuletzt am 04.08.08 um 20:16:31 editiert. |