DataMapper IDataReader method

DataMapper IDataReader method

Old forum URL: forums.lhotka.net/forums/t/11364.aspx


c_manboy posted on Thursday, May 17, 2012

A created a method in DataMapper called MapReader which takes an IDataReader object as a source. Will this method introduce any issues that I'm not seeing?  or is there a built in csla way of mapping a datareader to an object?

        Public Shared Sub MapReader(source As IDataReader, target As Object, suppressExceptions As BooleanParamArray ignoreList As String())
            Dim ignore As New List(Of String)(ignoreList)
 
            For Each propertyName In GetReaderPropertyNames(source)
                If Not ignore.Contains(propertyName) Then
                    Try
                        Dim value As Object = source.GetValue(source.GetOrdinal(propertyName))
                        If value Is DBNull.Value Then
                            value = Nothing
                        End If
                        SetPropertyValue(target, propertyName, value)
                    Catch ex As Exception
                        If Not suppressExceptions Then
                            Throw New ArgumentException([String].Format("{0} ({1})"Resources.PropertyCopyFailed, propertyName), ex)
                        End If
                    End Try
                End If
            Next
        End Sub
        Private Shared Function GetReaderPropertyNames(source As ObjectAs IList(Of String)             Dim result As New List(Of String)()             For index As Integer = 0 To source.FieldCount - 1                 result.Add(source.GetName(index))             Next             Return result         End Function

JonnyBee replied on Friday, May 18, 2012

No, there is n builtin support for IDataReader - but CSLA does introduce a SafeDataReader that wraps an IDataReader and will replace Null values with the default value of the type. This is under the assumption (and especially true for DataBinding in  Windows Forms) that you do NOT want to use nullable properties in your business objects.

I'd probably reduce the code somewhat to this:

Public Shared Sub MapReader(source As IDataReader, target As Object, suppressExceptions As Boolean, ParamArray ignoreList As String())
    For index As var = 0 To source.FieldCount - 1
        Dim propertyName = source.GetName(index)
        If ignoreList.Any(Function(p) p = propertyName) Then
            Continue For
        End If

        Try
            Dim value As Object = Nothing
            If Not source.IsDBNull(index) Then
                value = source.GetValue(index)
            End If
            SetPropertyValue(target, propertyName, value)
        Catch ex As Exception
            If Not suppressExceptions Then
                Throw New ArgumentException([String].Format("{0} ({1})", Resources.PropertyCopyFailed, propertyName), ex)
            End If
        End Try
    Next
End Sub

or in C#:

    public static void MapReader(IDataReader source, object target, bool suppressExceptions, params string[] ignoreList)
    {
        for (var index = 0; index <= source.FieldCount - 1; index++)
        {
            var propertyName = source.GetName(index);
            if (ignoreList.Any(p => p == propertyName)) continue;
 
            try
            {
                object value = null;
                if (!source.IsDBNull(index))
                    value = source.GetValue(index);
                SetPropertyValue(target, propertyName, value);
            }
            catch (Exception ex)
            {
                if (!suppressExceptions)
                {
                    throw new ArgumentException(
                        String.Format("{0} ({1})", 
                                      Resources.PropertyCopyFailed, propertyName), ex);
                }
            }
        }
    }

 

Copyright (c) Marimer LLC