dbObject - 使用属性进行数据库代码生成






3.95/5 (6投票s)
2006年1月26日
4分钟阅读

55442

434
一个简易的 OR 工具,用于根据 MySQL 数据库生成 VB.NET 数据库代码。
引言
这是一个我编写的示例框架。它的工作方式基本上类似于一个简易的 OR 工具,从数据库表生成 VB.NET 代码,并使用属性来控制更新和插入。
在设计系统时,我通常喜欢从数据库设计开始。使用数据模型可以帮助我想象系统将由哪些对象组成。在“对象挖掘”过程中,关于新系统最容易收集的信息是将被推送的数据。
使用 Microsoft 的 Recordset
是一种将表抽象为对象的绝佳方法。我遇到的问题是,当我尝试将 Recordset
与 MySQL 一起使用时,许多漂亮的钣金都脱落了。我开始编写自己的访问层,但发现自己一遍又一遍地重写相同的基本代码。显然,需要一个代码生成器。
因此,通过这种方法,我从表布局生成代码,每个字段都变成一个属性。通过检查数据库表的架构,我可以将属性应用于生成的 VB.NET 代码,并构造辅助函数来选择和更新底层数据。
背景
有很多关于基于属性的编程的优秀文章,其中一些就在 Code Project 上。MySQL 信息可以在这里找到。
使用代码
这里提供的代码是我在几个项目中使用的代码的摘录。此外,我编写了一个 Visual Studio .NET 插件,可以生成代码并将代码添加到我正在处理的项目中。
要使用此代码,您需要在您的机器上安装、配置和运行 MySQL。您还应该安装 MySQL 的 ODBC 连接器。涵盖这些方面超出了本文的范围。
您需要创建一个名为“dbObject”的数据库。您应该创建一个指向“dbObject”表的 ODBC 数据源,并测试连接。
在“dbObject”数据库中创建一个测试表。
DROP TABLE IF EXISTS `dbobject`.`protocols`;
CREATE TABLE `dbobject`.`protocols` (
`ProtocolType` varchar(20) NOT NULL default '',
`Enabled` varchar(1) NOT NULL default '',
`RootLocation` varchar(255) NOT NULL default '',
PRIMARY KEY (`ProtocolType`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
COMMENT='Sample table to hold communication protocol descriptions.';
运行该程序会显示一个简单的 Windows 窗体,允许选择数据库和表。
- 按“连接”按钮,使用文本框中显示的连接字符串连接到 MySQL 数据库。
- 选择一个数据库,然后选择一个表。
- 单击“选择”按钮,从所选表的架构生成 VB.NET 代码。
生成 VB.NET 类的实际代码非常简单
' Instance a code generator and set the various props
Dim oGeneratorSQL As New cGenerate_SQL
oGeneratorSQL.ConnectionString = oSelectTable.ConnectionString
oGeneratorSQL.DatabaseName = oSelectTable.DatabaseName
oGeneratorSQL.TableName = oSelectTable.TableName
oGeneratorSQL.UseDBFramework = True
oGeneratorSQL.InsertFrameworkIfMissing = False
' Instance a form to display the generated code
Dim oCodeViewer As New frmViewCode
' Generate the code and show the form
oCodeViewer.RichTextBox1.Text = oGeneratorSQL.GenerateInsertCode()
oCodeViewer.ShowDialog()
示例程序打开一个带有富文本框控件的窗体。生成的 VB.NET 代码设置为富文本框的 Text
属性。在我的 Visual Studio 插件中,我使用 Environment DTE 将生成的代码插入到当前光标位置。
关注点
因为我打算将代码生成用于 Visual Studio 插件的各种功能,所以我设计了对象的生成以共享一个通用接口,以便以后可以扩展该功能。
其中一个类,cGenerateProperty
对象,我经常在另一个 Visual Studio 插件中使用,该插件生成成员变量和属性访问器方法。右键单击“插入属性”并键入“CustomerName”,然后让该插件生成所有需要的代码,这样会容易得多。
dbObject_Framework
大多数操作发生在 dbObject_Framework
中。当代码生成器创建一个对象时,它会从框架中的 cBase_DBObj
类继承它。
Public Class cJobs Inherits cBase_DBObj
End Class
dbObject_Framework
处理大部分繁重的工作。我使用反射来获取关于给定类的各种信息,然后基于这些信息生成 SQL 命令来插入、更新等。
' Instantiate a new object of the passed in ClassName
Dim vbObj As Object = oThis.CreateInstance(sClassName, False, _
BindingFlags.Default, Nothing, Nothing, Nothing, Nothing)
' Get the Type object for this class,
' and from the type, get the properties
Dim vbClassType As Type = oThis.GetType(sClassName)
Dim oProps() As Reflection.PropertyInfo = Me.GetType.GetProperties()
For Each oProp As Reflection.PropertyInfo In oProps
Dim sPropName As String = oProp.Name
Dim sIsSerializable As String = _
oDriver.GetPropertyAttribute(oThis, _
sClassNameShort, sPropName, _
"IsSerializable").ToUpper
' Only attempt the read the property
' from the database if the property
' is marked "Serializable" via an attribute
If sIsSerializable = "TRUE" Then
' Get the type code of the data from the database
Dim oDBType As TypeCode = _
Type.GetTypeCode(oRS(sPropName).GetType)
' Get the type code of the property on the object
Dim oPropType As TypeCode = _
Type.GetTypeCode(oProp.PropertyType)
' Convert the data
If oDBType <> oPropType Then
' Convert the database data type
' into the object's property data type
' Note: In a future version that generates
' custom property types from the database,
' this marshalling step will not have
' to happen, since the types should agree...
Select Case Type.GetTypeCode(oProp.PropertyType)
Case TypeCode.String
oProp.SetValue(vbObj, _
oRS(sPropName).ToString, Nothing)
Case TypeCode.Boolean
Dim iTemp As Integer = oRS(sPropName)
If iTemp = 0 Then
oProp.SetValue(vbObj, False, Nothing)
Else
oProp.SetValue(vbObj, True, Nothing)
End If
Case Else
' Treat it like a string
oProp.SetValue(vbObj, oRS(sPropName), Nothing)
End Select
Else ' They match, so straight convert
' Set the property values from the database
oProp.SetValue(vbObj, oRS(sPropName), Nothing)
End If
End If
Next
使用此工具生成的类只是创建对象并调用 GetSelectedRecords
函数的问题。GetSelectedRecords
函数是从 dbObject_Framework
继承的。它返回一个符合条件的对象的 ArrayList
。
ArrayList = Object.GetSelectedRecords( criteria, connectionString)
在下面的示例代码中,我们实例化一个新的 cMerchants
对象,并调用它的 GetSelectedRecords()
方法。您可以通过 SQL WHERE
子句的形式传递一个可选的过滤器语句。
GetSelectedRecords()
函数检查类结构,生成正确的 SQL 查询,针对数据库运行查询,并将结果作为 cMerchants
对象的 ArrayList
返回。
Dim oDown As New cMerchants
Dim sConn As String = _
ConfigurationSettings.AppSettings("DBConnKey")
Dim sSQL As String = "WHERE MerchantID = '" _
& sMerchantID & "'"
Dim oArrayMerchants As New ArrayList
oArrayMerchants = oDown.GetSelectedRecords(sSQL, sConn)
If oArrayMerchants.Count > 0 Then
' Do Something
End If
历史
- 2006-01-26 - 首次提交到 Code Project。