12
返回列表 发新帖
楼主: jieforest

微型ORM

[复制链接]
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
11#
 楼主| 发表于 2010-2-12 12:11 | 只看该作者
Public Overrides Function TryInvokeMember(

    ByVal binder As System.Dynamic.InvokeMemberBinder,

    ByVal args() As Object,

    ByRef result As Object) As Boolean



    Dim manageConnectionLifespan = (m_Connection.State = ConnectionState.Closed)

    If manageConnectionLifespan Then m_Connection.Open()



    Try

        Using cmd As New SqlClient.SqlCommand(binder.Name, m_Connection)

            cmd.CommandType = CommandType.StoredProcedure



            If binder.CallInfo.ArgumentNames.Count <> binder.CallInfo.ArgumentCount Then

                Throw New ArgumentException("All parameters must be named")

            End If



            For i = 0 To binder.CallInfo.ArgumentCount - 1

                Dim param As New SqlClient.SqlParameter

                param.ParameterName = "@" & binder.CallInfo.ArgumentNames(i)

                param.Value = If(args(i) Is Nothing, DBNull.Value, args(i))

                cmd.Parameters.Add(param)

            Next



            Select Case m_Options

                Case CallingOptions.Scalar

                    result = ExecuteScalar(cmd)

                Case CallingOptions.Single

                    result = ExecuteSingle(cmd)

                Case CallingOptions.List

                    result = ExecuteList(cmd)

                Case CallingOptions.MultipleLists

                    result = ExecuteMultpleLists(cmd)

                Case Else

                    Throw New ArgumentOutOfRangeException("options")

            End Select

        End Using

    Finally

        If manageConnectionLifespan Then m_Connection.Close()

    End Try



    Return True

End Function

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
12#
 楼主| 发表于 2010-2-12 12:11 | 只看该作者
ExecuteScalar方法很简单,它拥有自己方法的唯一原因是要保持一致性。

Private Function ExecuteScalar(ByVal command As SqlCommand) As Object

    Dim temp = command.ExecuteScalar

    If temp Is DBNull.Value Then Return Nothing Else Return temp

End Function

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
13#
 楼主| 发表于 2010-2-12 12:11 | 只看该作者
对于剩下的变量,调用者期望是真正的属性,或者至少看起来像属性。一种选择是基于运行时结果集的内容自动生成代码的类。但是在运行时生成代码会耗费大量的资源,并且我们不会从中得到太多好处,因为没有哪个调用者会通过名字来引用我们的类。因此,在保持动态代码的模式的时候,我们选择使用原型动态对象来替换它。

Friend Class MicroDataObject

    Inherits Dynamic.DynamicObject

    Private m_Values As New Dictionary(Of String, Object)(StringComparer.OrdinalIgnoreCase)



    Public Overrides Function TryGetMember(ByVal binder As System.Dynamic.GetMemberBinder, ByRef result As Object) As Boolean

        If m_Values.ContainsKey(binder.Name) Then result = m_Values(binder.Name) Else Throw New System.MissingMemberException("The property " & binder.Name & " does not exist")

        Return True

    End Function



    Public Overrides Function TrySetMember(ByVal binder As System.Dynamic.SetMemberBinder, ByVal value As Object) As Boolean

        SetMember(binder.Name, value)

        Return True

    End Function



    Public Overrides Function GetDynamicMemberNames() As System.Collections.Generic.IEnumerable(Of String)

        Return m_Values.Keys

    End Function



    Friend Sub SetMember(ByVal propertyName As String, ByVal value As Object)

        If value Is DBNull.Value Then m_Values(propertyName) = Nothing Else m_Values(propertyName) = value

    End Sub



End Class

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
14#
 楼主| 发表于 2010-2-12 12:11 | 只看该作者
由于任何类都不会依赖于这个对象,因此我们再次将其标记为Friend(C#的internal修饰符)。这还剩下三个用来管理属性的重写方法:一个用来设置属性,一个用来取得属性,还有一个用来列出属性的名称。另外,还有一个用来使用静态类型代码初始化类的后门方法。

Private Function ExecuteSingle(ByVal command As SqlCommand) As Object

    Using reader = command.ExecuteReader

        If reader.Read Then

            Dim dataObject As New MicroDataObject

            For i = 0 To reader.FieldCount - 1

                dataObject.SetMember(reader.GetName(i), reader.GetValue(i))

            Next

            Return dataObject

        Else

            Return Nothing

        End If

    End Using

End Function



Private Function ExecuteList(ByVal command As SqlCommand) As List(Of MicroDataObject)

    Dim resultList = New List(Of MicroDataObject)

    Using reader = command.ExecuteReader

        Do While reader.Read

            Dim dataObject As New MicroDataObject

            For i = 0 To reader.FieldCount - 1

                dataObject.SetMember(reader.GetName(i), reader.GetValue(i))

            Next

            resultList.Add(dataObject)

        Loop

    End Using

    Return resultList

End Function



Private Function ExecuteMultpleLists(ByVal command As SqlCommand) As List(Of List(Of MicroDataObject))

    Dim resultSet As New List(Of List(Of MicroDataObject))



    Using reader = command.ExecuteReader

        Do



            Dim resultList = New List(Of MicroDataObject)

            Do While reader.Read

                Dim dataObject As New MicroDataObject

                For i = 0 To reader.FieldCount - 1

                    dataObject.SetMember(reader.GetName(i), reader.GetValue(i))

                Next

                resultList.Add(dataObject)

            Loop

            resultSet.Add(resultList)



        Loop While reader.NextResult

    End Using



    Return resultSet

End Function

你刚刚创建的“微型ORM”还有很大的改善空间。可能会增加的特性有:添加对输出参数的支持;选择发送参数化的查询而不是存储过程名称;对其它数据库的支持等等。

使用道具 举报

回复
论坛徽章:
131
乌索普
日期:2017-09-26 13:06:30马上加薪
日期:2014-11-22 01:34:242014年世界杯参赛球队: 尼日利亚
日期:2014-06-17 15:23:23马上有对象
日期:2014-05-11 19:35:172014年新春福章
日期:2014-04-04 16:16:58马上有对象
日期:2014-03-08 16:50:54马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14
15#
发表于 2010-2-13 22:41 | 只看该作者
nice job

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表