ORM(三)实体
实体定义
由于我目前是在winform下进行开发,如果采用xml来进行影射关系,我觉得有点复杂。采用属性来描述,我又觉得控制起来不方便。所以就把字段的定义转换为类,成为实体的公共属性。实体是能过反射来发现自己有那些实体字段IEntityField。
下面我们来看看一个实体的定义,我是根据Northwind数据库是的表进行示例的。
Imports Lily
Imports Lily.Core
Imports System.ComponentModel
Public Class Shippers
Inherits EntityBase
#Region "类实例化"
Public Sub New()
MyBase.new()
End Sub
Public Sub New(ByVal isautoLoad As Boolean)
MyBase.New(isautoLoad)
End Sub
#End Region
#Region "实体字段描述"
Private f_ShipperID As IEntityField
<Browsable(False)> _
Public Overridable ReadOnly Property _ShipperID() As IEntityField
Get
If f_ShipperID Is Nothing Then
f_ShipperID = CoreFactory.GetEntityField(Me, "ShipperID", "ShipperID", True, False, DbType.Int32, 4)
End If
Return f_ShipperID
End Get
End Property
Private f_CompanyName As IEntityField
<Browsable(False)> _
Public Overridable ReadOnly Property _CompanyName() As IEntityField
Get
If f_CompanyName Is Nothing Then
f_CompanyName = CoreFactory.GetEntityField(Me, "CompanyName", "CompanyName", False, False, DbType.String, 40)
End If
Return f_CompanyName
End Get
End Property
Private f_Phone As IEntityField
<Browsable(False)> _
Public Overridable ReadOnly Property _Phone() As IEntityField
Get
If f_Phone Is Nothing Then
f_Phone = CoreFactory.GetEntityField(Me, "Phone", "Phone", False, False, DbType.String, 24)
End If
Return f_Phone
End Get
End Property
#End Region
#Region "实体属性"
Private md_ShipperID As Integer
<Browsable(True)> _
Public Overridable Property ShipperID() As Integer
Get
Return md_ShipperID
End Get
Set(ByVal Value As Integer)
md_ShipperID = Value
Me.OnPropertyChanged("ShipperID")
End Set
End Property
Private md_CompanyName As String = String.Empty
<Browsable(True)> _
Public Overridable Property CompanyName() As String
Get
Return md_CompanyName
End Get
Set(ByVal Value As String)
md_CompanyName = Value
Me.OnPropertyChanged("CompanyName")
End Set
End Property
Private md_Phone As String = String.Empty
<Browsable(True)> _
Public Overridable Property Phone() As String
Get
Return md_Phone
End Get
Set(ByVal Value As String)
md_Phone = Value
Me.OnPropertyChanged("Phone")
End Set
End Property
#End Region
#Region "设置实体的属性"
Public Overrides Sub SetValue(ByVal attributename As String, ByVal value As Object)
Select Case attributename
Case "ShipperID"
ShipperID = value
Case "CompanyName"
CompanyName = value
Case "Phone"
Phone = 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 "ShipperID"
Return ShipperID
Case "CompanyName"
Return CompanyName
Case "Phone"
Return Phone
Case Else
Return MyBase.GetValue(attributename)
End Select
End Function
#End Region
#Region "实体其它属性"
<Browsable(False)> _
Public ReadOnly Property Guid() As String
Get
Return "a
End Get
End Property
<Browsable(False)> _
Public Overrides ReadOnly Property TableName() As String
Get
Return "Shippers"
End Get
End Property
<Browsable(False)> _
Public Overrides ReadOnly Property AutoIncrement() As IEntityField
Get
Return _ShipperID
End Get
End Property
#End Region
End Class
1.关于SetValue和GetValue方法
主要是用反射进行获取和设置时效率比较低的原因。
2.Guid
还没有想好怎么用,主要是想在系统中保证唯一性。
3.TableName
返回实体所在的表。
4.AutoIncrement返回自动增长的字段。
当前的设计有一个不好之处就是,如果你要进行数据更新和删除如果想让系统自己来做,那必须要有一个自动增长字段,当前你只是用于查询那就只是返回Nothing就行了。
5.字段的描述
可以描述自己的类型,大小,对应数据库的字段名称,对应类的属性名称,是否是自动增长,是否是主键(这里的主键是认为在数据库中记录不能重复的字段,在进行更新和删除时系统会自动进行判断),是否是虚拟字段(虚拟字段主要是用于在绑定,更新时不会进行数据操作,而只是显示。),是否是联合主键(即在同一个表中,两个字段的值联合起来应当是唯一,这样在进行更新和插入时会自动进行判断)。
实体操作
插入实体
Dim o As New Lily.Core.EntityHandler
Dim en As New Shippers
en.CompanyName = "zqonline"
en.Phone = "8182329X"
o.Accept(en)
更新实体
Dim o As New Lily.Core.EntityHandler
Dim en As New Shippers(True)
en.SetEntityState(Lily.Core.EntityState.Unchanged)
With en
.CompanyName = "zqonline"
.Phone = "8182329X"
.ShipperID = 11
End With
o.Accept(en)
此时实体调用了实例化的重载方法。并且必须把实体的状态设为Unchanged.同时对实体的ShipperID进行了赋值。如果没有指定ShipperID的值,将会进行插入操作。其实对于使用中我们的更新往往不是这样的,因为这样显得太烦琐了。
如果之前我们从数据库中获取了一个实体。
Dim o As New Lily.Core.Operate
Dim en As New Shippers
en = o.GetEntity(en._ShipperID.EqualTo(1), en)
OQL语句示例:
更新命令
With en
Dim command As ICommand = SQL.Update(en, ._CompanyName.Update("zqonline"), ._Phone.Update("8182329X")).From(en).WHERE(._ShipperID.EqualTo(11))
o.ExecuteNonQuery(command)
End With
查询命令
With en
command = SQL.Select().From(en).WHERE(._ShipperID.EqualTo(11))
o.ExecuteNonQuery(command)
end with
这里我们从数据库中获取了ShipperID=1的一条记录,并返回实体,我们假设此记录存在,并要修改其电话号码,下面就是修改的例子。
Dim o As New Lily.Core.Operate
en.Phone = "110"
o.Accept(en)
删除实体
Dim o As New Lily.Core.EntityHandler
Dim en As New Shippers
en.ShipperID = 1
en.SetEntityState(EntityState.Deleted)
o.Accept(en)
上面我们都手动的更改了实体的状态,其实在使用中我们是没有这个步骤的。因为每个实体都有一个专门的操作类,现在实用的是实体通用的操作类。所以必须要进行此操作。
OQL语句:
Dim command As ICommand = SQL.Delete(en).From(en).WHERE(en._ShipperID.EqualTo(1))
o.ExecuteNonQuery(command)
通过上面的演示,是否对整个实体的操作有了大概的了解呢。