Vibrant discussion about CSLA .NET and using the framework to build great business applications.
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 Boolean, ParamArray 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 Object) As 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
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 NextEnd 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); } } } }
Jonny Bekkum, Norway CslaContrib Coordinator