使用VB.Net写一个简单的数据访问层(不能称ORM):前言
使用.Net多年,没有什么进步,比较困惑。可能是非主流的原因,很多时候一个问题,能用代码来解决,确无法用文字来解释,为了增强这方面的功力,接下来把自己正在开发的一个数据层拿出来说话。可能这是在重复造轮子,对于小系统来说自己造的轮子,也许用起来更顺手。
此物的目的:也就是一个数据访问的功能。
希望能支持多种数据库:
- Access2000,写一个小东西用它还是不错的。
- SQLSERVER,不用说,肯定要支持它,我也只对它比较熟一些。
- MySql,有时使用SQLSERVER增加了客户的成本,不过这个东西维护人员也不好找吧,当然你用盗版列外。当然我还没有用过,在写这个组件的同时,慢慢学习。
以下是在接下来的演示中需要用到的表结构图:
这里有三个表,实体与表是一对一的。也相应的有三个实体,实体我一般都是放在命名空间Common下的。下面我简单的列出主表的实体代码。
Imports At.Data Imports At.Core Imports System.ComponentModel Namespace Common Public Class 主表 Inherits EntityBase #Region "类实例化" Public Sub New() MyBase.new() End Sub #End Region #Region "实体字段描述" Private f_ID As IEntityField <Browsable(False)> _ Public Overridable ReadOnly Property _ID() As IEntityField Get If f_ID Is Nothing Then f_ID = Me.DataHelper.GetEntityField(Me, "ID", "ID", True, False, DbType.Int32, 4) End If Return f_ID End Get End Property Private f_物品编号 As IEntityField <Browsable(False)> _ Public Overridable ReadOnly Property _物品编号() As IEntityField Get If f_物品编号 Is Nothing Then f_物品编号 = Me.DataHelper.GetEntityField(Me, "物品编号", "物品编号", False, False, DbType.String, 50) End If Return f_物品编号 End Get End Property Private f_物品名称 As IEntityField <Browsable(False)> _ Public Overridable ReadOnly Property _物品名称() As IEntityField Get If f_物品名称 Is Nothing Then f_物品名称 = Me.DataHelper.GetEntityField(Me, "物品名称", "物品名称", False, False, DbType.String, 50) End If Return f_物品名称 End Get End Property Private f_物品型号 As IEntityField <Browsable(False)> _ Public Overridable ReadOnly Property _物品型号() As IEntityField Get If f_物品型号 Is Nothing Then f_物品型号 = Me.DataHelper.GetEntityField(Me, "物品型号", "物品型号", False, False, DbType.String, 50) End If Return f_物品型号 End Get End Property Private f_单位 As IEntityField <Browsable(False)> _ Public Overridable ReadOnly Property _单位() As IEntityField Get If f_单位 Is Nothing Then f_单位 = Me.DataHelper.GetEntityField(Me, "单位", "单位", False, False, DbType.String, 50) End If Return f_单位 End Get End Property Private f_生产厂家 As IEntityField <Browsable(False)> _ Public Overridable ReadOnly Property _生产厂家() As IEntityField Get If f_生产厂家 Is Nothing Then f_生产厂家 = Me.DataHelper.GetEntityField(Me, "生产厂家", "生产厂家", False, False, DbType.String, 50) End If Return f_生产厂家 End Get End Property Private f_库存量 As IEntityField <Browsable(False)> _ Public Overridable ReadOnly Property _库存量() As IEntityField Get If f_库存量 Is Nothing Then f_库存量 = Me.DataHelper.GetEntityField(Me, "库存量", "库存量", False, False, DbType.Decimal, 9) End If Return f_库存量 End Get End Property Private f_库存金额 As IEntityField <Browsable(False)> _ Public Overridable ReadOnly Property _库存金额() As IEntityField Get If f_库存金额 Is Nothing Then f_库存金额 = Me.DataHelper.GetEntityField(Me, "库存金额", "库存金额", False, False, DbType.Decimal, 9) End If Return f_库存金额 End Get End Property #End Region #Region "实体属性" Private md_ID As Integer <Browsable(True)> _ Public Overridable Property ID() As Integer Get Return md_ID End Get Set(ByVal Value As Integer) If value <> md_ID Then md_ID = Value Me.OnPropertyChanged("ID") End If End Set End Property Private md_物品编号 As String = String.Empty <Browsable(True)> _ Public Overridable Property 物品编号() As String Get Return md_物品编号 End Get Set(ByVal Value As String) If value <> md_物品编号 Then md_物品编号 = Value Me.OnPropertyChanged("物品编号") End If End Set End Property Private md_物品名称 As String = String.Empty <Browsable(True)> _ Public Overridable Property 物品名称() As String Get Return md_物品名称 End Get Set(ByVal Value As String) If value <> md_物品名称 Then md_物品名称 = Value Me.OnPropertyChanged("物品名称") End If End Set End Property Private md_物品型号 As String = String.Empty <Browsable(True)> _ Public Overridable Property 物品型号() As String Get Return md_物品型号 End Get Set(ByVal Value As String) If value <> md_物品型号 Then md_物品型号 = Value Me.OnPropertyChanged("物品型号") End If End Set End Property Private md_单位 As String = String.Empty <Browsable(True)> _ Public Overridable Property 单位() As String Get Return md_单位 End Get Set(ByVal Value As String) If value <> md_单位 Then md_单位 = Value Me.OnPropertyChanged("单位") End If End Set End Property Private md_生产厂家 As String = String.Empty <Browsable(True)> _ Public Overridable Property 生产厂家() As String Get Return md_生产厂家 End Get Set(ByVal Value As String) If value <> md_生产厂家 Then md_生产厂家 = Value Me.OnPropertyChanged("生产厂家") End If End Set End Property Private md_库存量 As Decimal <Browsable(True)> _ Public Overridable Property 库存量() As Decimal Get Return format(md_库存量, "0.######") End Get Set(ByVal Value As Decimal) If value <> md_库存量 Then md_库存量 = Value Me.OnPropertyChanged("库存量") End If End Set End Property Private md_库存金额 As Decimal <Browsable(True)> _ Public Overridable Property 库存金额() As Decimal Get Return format(md_库存金额, "0.######") End Get Set(ByVal Value As Decimal) If value <> md_库存金额 Then md_库存金额 = Value Me.OnPropertyChanged("库存金额") End If End Set End Property #End Region #Region "设置实体的属性" Public Overrides Sub SetValue(ByVal attributename As String, ByVal value As Object) Select Case attributename Case "ID" ID = value Case "物品编号" 物品编号 = value Case "物品名称" 物品名称 = value Case "物品型号" 物品型号 = value Case "单位" 单位 = value Case "生产厂家" 生产厂家 = value Case "库存量" 库存量 = value Case "库存金额" 库存金额 = value Case Else MyBase.SetValue(attributename, value) End Select End Sub #End Region #Region "获取实体的属性" Public Overrides Function GetValue(ByVal attributename As String) As Object Select Case attributename Case "ID" Return ID Case "物品编号" Return 物品编号 Case "物品名称" Return 物品名称 Case "物品型号" Return 物品型号 Case "单位" Return 单位 Case "生产厂家" Return 生产厂家 Case "库存量" Return 库存量 Case "库存金额" Return 库存金额 Case Else Return MyBase.GetValue(attributename) End Select End Function #End Region #Region "实体其它属性" <Browsable(False)> _ Public ReadOnly Property Guid() As String Get Return "aee5307acf2a24a0a8e1f5c650d5e24d6" End Get End Property <Browsable(False)> _ Public Overrides ReadOnly Property TableName() As String Get Return "主表" End Get End Property <Browsable(False)> _ Public Overrides ReadOnly Property AutoIncrement() As IEntityField Get Return _ID End Get End Property #End Region End Class End Namespace
表里的每个字段映射到实体对象的实体字段(IEntityField对象),这里没有采用XML配置文件或属性的方式。使用XML文件太繁杂,特别是系统经常进行调整和修改时会很头痛。属性的方式比较字段,但是不能按一个常规对象来进行访问。曾在前两年使用过这种方式。
属性解说:
TableName:对应的是数据库的表名,有时我们可能需要在同一服务器上进行跨库访问,可以不用修改数据库连接字符串,直接设置实体对象的DbName名称就可以,以后会有这方面的例子。
AutoIncrement:是对应的自动增长字段,虽然我们可以通过IEntityField对象可以判断出那个字段是AutoIncrement的,这样需要一个循环,所以这里就单独的公开了一个属性。如果需要对实体进行CRUD操作,则必须要设置一个字段为自动增长字段。当然你可以不设,那么CRUD操作,就需要你自己写代码了。
Guid:这个属性没有实际意义,正在考虑,是否去掉。
SetValue,GetValue:这个方法是重写基类的,基类的SetValue和GetValue是使用反射的形式把DataRow对象转换为一个实体对象,反射的效率比较差,所以这里就采用了折衷的方法,使用硬编码。
OnPropertyChanged:这个方法用于当字段的值发生变化时,引发一个事件。
DataHelper.GetEntityField:用于根据当前数据库获取一个字段描述对象,我称为字段对象。
对这个实体对象就简单介绍完了,如果您有兴趣讲继续关注。一个简单的数据访问层!