Hydrating your Business Objects - Part 1, The CBO class

http://www.charlesnurse.com/post/Hydrating-your-Business-Objects-Part-1-The-CBO-class.aspx

This article is based on material originally published on DNN Developer Zone (www.dnndevzone.com).  This version has been updated to cover the changes made in DotNetNuke 5.0.

Introduction

In a Blog a few months agoon DotNetNuke.com I described the results of some profiling tests I had carried out. In that blog I discussed the CBO class, when to use it and more importantly, when not to use it.  Since writing that Blog post there have been some changes to how the CBO class works.  This article will focus on how the CBO class works and how it can be used - in a future article I will describe the IHydratable Interface, and how it can be used to improve performance.

The CBO Class

The CBO class is a utility class in the DotNetNuke Library that performs Business Object hydration. Hydration is a term that refers to the filling of an instance of a class, in this case from a DataReader. CBO exposes both standard and generic versions of two methods; FillObject (which is used to hydrate a single object) and FillCollection (which is used to hydrate a collection of objects), as well as multiple versions of a generic FillDictionary method.

These methods take the type of the object to hydrate as a parameter and use reflection to determine how to hydrate the object. As discussed in the blog entry, reflection is an expensive process and could be replaced by writing custom hydrators. Let's first examine the process to hydrate a single object instance in the Links module (LinkController.GetLink()) using the CBO class. Later in this article we will describe how to use a custom hydrator that avoids the use of reflection thus improving performance.

Listing 1: The GetLink method in the LinkController Class
   1:  Public Function GetLink(ByVal ItemID As Integer, ByVal ModuleId As Integer) As LinkInfo
   2:      Return CType(CBO.FillObject(DataProvider.Instance().GetLink(ItemID, ModuleId),_
GetType(LinkInfo)), LinkInfo)
   3:  End Function

Listing 1 shows the GetLink method in the LinkController class. This method is fairly straightforward, as it calls a similarly named method in the DataProvider, which returns a DataReader containing a single link identified by the ItemId and Module Id. This DataReader is then passed to the FillObject method together with the type of object to fill (LinkInfo in this case).

Using the FillObject method to hydrate a single object

The FillObject method of the CBO class called above is a static (or shared) method that takes a DataReader and a type as parameters and returns an object. This method has an override that also takes a Boolean property - closeReader- that determines whether to close the DataReader after the object has been created (see Listing 2).

Listing 2: The FillObject methods
   1:  Public Shared Function FillObject(ByVal dr As IDataReader, ByVal objType As Type) As Object
   2:      Return CreateObjectFromReader(objType, dr, True)
   3:  End Function
   4:   
   5:  Public Shared Function FillObject(ByVal dr As IDataReader, ByVal objType As Type, 
                                         ByVal closeReader As Boolean) As Object
   6:      Return CreateObjectFromReader(objType, dr, closeReader)
   7:  End Function

This override is used for situations when the the caller needs to continue to use the IDataReader. An example of this would be when Data Layer returns two or more sets of data, one is used to hydrate one set of objects and the other is used for some other reason - perhaps to hydrate a second set of objects.  Both overrides call the private method CreateObjectFromReader (Listing 3)

Listing 3: CreateObjectFromReader
   1:  Private Shared Function CreateObjectFromReader(ByVal objType As Type, ByVal dr As IDataReader, 
                                                      ByVal closeReader As Boolean) As Object
   2:      Dim objObject As Object = Nothing
   3:   
   4:      Dim canRead As Boolean = True
   5:      If closeReader Then
   6:          canRead = False
   7:          ' read datareader
   8:          If dr.Read() Then
   9:              canRead = True
  10:          End If
  11:      End If
  12:   
  13:      If canRead Then
  14:          'Create the Object
  15:          objObject = CreateObject(objType, False)
  16:   
  17:          'hydrate the custom business object
  18:          FillObjectFromReader(objObject, dr)
  19:      End If
  20:   
  21:      ' Ensure DataReader is closed
  22:      CloseDataReader(dr, closeReader)
  23:   
  24:      Return objObject
  25:  End Function

The first part of this method (lines 4-11) determine if there is a record to read.  Next in line 15 we create an object of the correct type and in line 18 we call FillObjectFromReader to hydrate the object from the DataReader.

Before we look in detail at the FillObjectFromReader method lets examine how the FillCollection methods work.

Using the FillCollection method to hydrate a collection of objects

The public FillCollection methods behave similarly.  In the Links module, for example, the LinksController class has a method to return all the Links

Listing 4: The GetLinks method in the LinkController Class
   1:  Public Function GetLinks(ByVal ModuleId As Integer) As ArrayList
   2:      Return CBO.FillCollection(DataProvider.Instance().GetLinks(ModuleId), GetType(LinkInfo))
   3:  End Function

This method calls the FillCollection method, passing, as before, the DataReader and the type of the object to hydrate.

Listing 5: The FillCollection method
   1:  Public Shared Function FillCollection(ByVal dr As IDataReader, ByVal objType As Type) As ArrayList
   2:      Return DirectCast(FillListFromReader(objType, dr, New ArrayList(), True), ArrayList)
   3:  End Function

As with the case of the FillObject method the FillCollection method calls a private FillListFromReader method, which fills the collection passed to it with objects created from the DataReader (see Listing 6). 

Listing 6 The FillListFromReader method
   1:  Private Shared Function FillListFromReader(ByVal objType As Type, ByVal dr As IDataReader, 
                                  ByVal objList As IList, ByVal closeReader As Boolean) As IList
   2:      Dim objObject As Object
   3:   
   4:      ' iterate datareader
   5:      While dr.Read
   6:          'Create the Object
   7:          objObject = CreateObjectFromReader(objType, dr, False)
   8:   
   9:          ' add to collection
  10:          objList.Add(objObject)
  11:      End While
  12:   
  13:      ' Ensure DataReader is closed
  14:      CloseDataReader(dr, closeReader)
  15:   
  16:      Return objList
  17:  End Function

The important thing to note being that the FillListFromReader method calls the same CreateObjectFromReader method that is called by FillObject, with the closeReader parameter set to false.

The FillObjectFromReader method

As we have discussed above all calls to FillObject, FillCollection (and FillDictionary) are routed through the private method FillObjectFromDataReader (Listing 7)

Listing 7: The FillObjectFromReader method
   1:  Private Shared Sub FillObjectFromReader(ByVal objObject As Object, ByVal dr As IDataReader)
   2:      'Determine if object is IHydratable
   3:      If TypeOf objObject Is IHydratable Then
   4:          'Use IHydratable's Fill
   5:          Dim objHydratable As IHydratable = TryCast(objObject, IHydratable)
   6:          If objHydratable IsNot Nothing Then
   7:              objHydratable.Fill(dr)
   8:          End If
   9:      Else
  10:          'Use Reflection
  11:          HydrateObject(objObject, dr)
  12:      End If
  13:  End Sub

This method determines if the object implements the IHydratable interface (I will discus this interface in more detail in a future blog).  If it does it calls the objects Fill method, if not it calls the HydrateObject method which uses Reflection to hydrate the object (see Listing 8)

Listing 8: The HydrateObject method
   1:  Private Shared Sub HydrateObject(ByVal objObject As Object, ByVal dr As IDataReader)
   2:      Dim objPropertyInfo As PropertyInfo = Nothing
   3:      Dim objPropertyType As Type = Nothing
   4:      Dim objDataValue As Object
   5:      Dim objDataType As Type
   6:      Dim intIndex As Integer
   7:   
   8:      ' get cached object mapping for type
   9:      Dim objMappingInfo As ObjectMappingInfo = GetObjectMapping(objObject.GetType)
  10:   
  11:      ' fill object with values from datareader
  12:      For intIndex = 0 To dr.FieldCount - 1
  13:          'If the Column matches a Property in the Object Map's PropertyInfo Dictionary
  14:          If objMappingInfo.Properties.TryGetValue(dr.GetName(intIndex).ToUpperInvariant, 
objPropertyInfo) Then
  15:              'Get its type
  16:              objPropertyType = objPropertyInfo.PropertyType
  17:   
  18:              'If property can be set
  19:              If objPropertyInfo.CanWrite Then
  20:                  'Get the Data Value from the data reader
  21:                  objDataValue = dr.GetValue(intIndex)
  22:   
  23:                  'Get the Data Value's type
  24:                  objDataType = objDataValue.GetType
  25:   
  26:                  If IsDBNull(objDataValue) Then
  27:                      ' set property value to Null
  28:                      objPropertyInfo.SetValue(objObject, Null.SetNull(objPropertyInfo), Nothing)
  29:                  ElseIf objPropertyType.Equals(objDataType) Then
  30:                      'Property and data objects are the same type
  31:                      objPropertyInfo.SetValue(objObject, objDataValue, Nothing)
  32:                  Else
  33:                      ' business object info class member data type does not match  
  34:                      ' datareader member data type
  35:                      Try
  36:                          'need to handle enumeration conversions differently than other 
  37:                          'base(types)
  38:                          If objPropertyType.BaseType.Equals(GetType(System.Enum)) Then
  39:                              ' check if value is numeric and if not convert to integer 
  40:                              ' ( supports databases like Oracle )
  41:                              If IsNumeric(objDataValue) Then
  42:                                  objPropertyInfo.SetValue(objObject, System.Enum.ToObject(
objPropertyType, Convert.ToInt32(objDataValue)), Nothing)
  43:                              Else
  44:                                  objPropertyInfo.SetValue(objObject, System.Enum.ToObject(
objPropertyType, objDataValue), Nothing)
  45:                              End If
  46:                          ElseIf objPropertyType.FullName.Equals("System.Guid") Then
  47:                              ' guid is not a datatype common across all databases 
  48:                              ' ( ie. Oracle )
  49:                              objPropertyInfo.SetValue(objObject, Convert.ChangeType(
                                           New Guid(objDataValue.ToString()), objPropertyType), Nothing)
  50:                          ElseIf objPropertyType.FullName.Equals("System.Version") Then
  51:                              objPropertyInfo.SetValue(objObject, 
                                           New Version(objDataValue.ToString()), Nothing)
  52:                          Else
  53:                              ' try explicit conversion
  54:                              objPropertyInfo.SetValue(objObject, objDataValue, Nothing)
  55:                          End If
  56:                      Catch
  57:                          objPropertyInfo.SetValue(objObject, Convert.ChangeType(objDataValue, 
                                                           objPropertyType), Nothing)
  58:                      End Try
  59:                  End If
  60:              End If
  61:          End If
  62:      Next
  63:  End Sub

This blog describes the overall approach to hydration in the DotNetNuke LIbrary.  In Part 2 I will describe the IHydratable Interface, and how you can improve the performance of your own modules.


1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
应用背景为变电站电力巡检,基于YOLO v4算法模型对常见电力巡检目标进行检测,并充分利用Ascend310提供的DVPP等硬件支持能力来完成流媒体的传输、处理等任务,并对系统性能做出一定的优化。.zip深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。
深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。
深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。
深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 、资源5来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 、资源5来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。、 5资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值