Quantcast
Channel: VBForums - Visual Basic .NET
Viewing all articles
Browse latest Browse all 27336

VS 2010 Linq Expressions hanlde DBNull in runtime generated method

$
0
0
I am in the process of making my own very basic ORM and I am stuck. Right now I am trying to build a collection of my model classes from a datareader and I have it partially working. From what I have read you don't want to use reflection a lot as it is slow so I found this article: http://www.codeproject.com/Articles/...ion-techniques which suggets using Linq to dynamically build a new constructor for my model classes.

After a lot of headache converting C# to VB and removing the bits I didn't think I needed I ended up with this:

Code:

    Public Function GetReader() As Func(Of OleDbDataReader, Entity)

        Dim resDelegate As [Delegate]
        Dim body As BlockExpression
        Dim lambda As LambdaExpression
        Dim argtype(0) As Type
        argtype(0) = "".GetType()

        Dim statements As New List(Of Expression)                                                              'List of statements in our dynamic method
        Dim indexerProperty As PropertyInfo = GetType(OleDbDataReader).GetProperty("Item", argtype)            'Get the indexer property of the DataReader
        Dim instanceParam As ParameterExpression = Expression.Variable(GetType(T))                              'Instance type of target entity class
        Dim readerParam As ParameterExpression = Expression.Parameter(GetType(OleDbDataReader))                'Parameter for the SqlDataReader object
        Dim createInstance As BinaryExpression = Expression.Assign(instanceParam, Expression.[New](GetType(T)))

        statements.Add(createInstance)

        Dim propertyCol As New List(Of Expression)

        For Each prop As PropertyInfo In GetType(T).GetProperties()
            If IsNothing(GetType(T).BaseType.GetProperty(prop.Name)) Then
                Dim getProperty As MemberExpression = Expression.Property(instanceParam, prop)
                Dim readValue As IndexExpression = Expression.MakeIndex(readerParam, indexerProperty, New Expression() {Expression.Constant(prop.Name)})
                Dim assignProperty As BinaryExpression = Expression.Assign(getProperty, Expression.Convert(readValue, prop.PropertyType))
                statements.Add(assignProperty)
            End If
        Next

        Dim returnStatement = instanceParam
        statements.Add(returnStatement)

        body = Expression.Block(instanceParam.Type, {instanceParam}, statements.ToArray())
        lambda = Expression.Lambda(Of Func(Of OleDbDataReader, T))(body, readerParam)

        resDelegate = lambda.Compile()

        Return DirectCast(resDelegate, Func(Of OleDbDataReader, Entity))

    End Function


I don't have a very strong grasp on what exactly is going on with this as it seems pretty foreign. I have a general idea of what it is doing, building a custom delegate that accepts a datareader and outputs an entity (my base class for all my custom data models) It basically assumes a 1 to 1 association of the column name in the database to the property name in my class. The issue I am having is when I have a dbnull value in my database it cant cast to to my propertytype. So somewhere in the for each loop I am guessing I need to modify the expression to be more explicit in converting.

Like I said, I am completely new to linq and these expressions so I am still reading up on this but I don't know if it is even possible to have a conditional expression so I thought I would post this. Any help would be greatly appreciated!

Viewing all articles
Browse latest Browse all 27336

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>