只所以在MyRelation类中定义一些方法实现类似触发器的功能,其目的就像前面描述的那样,保证发送到数据库的数据是符合数据库的设计规则的。无论你是显式的写在数据库中,还是隐式的存在于业务逻辑中。
在大多数情况下,我们的数据环境中通常存在于多于一个的Cursor,它们通常是父子表关系或在业务逻辑上有关联。因此,我们需要使用MyRelation来解决它们之间的数据一致性。
这里,我们以插入触发器为例来解释一下如何实现。
首先,我们在MyRelation类增加一个名为Add的自定义方法,然后,再增加一个名为InsertTirgger的自定义方法。此外,为了使其具有更灵活的应用,我们增加一个lTirgger自定义属性,并设置其默认值为.F.。这样,我们的准备工作就基本完成了,余下的,就是在自定义方法中写入代码:
Add方法:
PrivatellResult
LocalllResultasLogical
m.llResult=This.InsertTirgger()
Returnm.llResult
返回值llResult为逻辑型,表示触发器执行是否成功。
InsertTirgger方法:
Return.T.
在自定义类中,仅需要这一行代码。因为默认情况下我们并不使用触发器。但是,在实际应用环境中,你需要在它的子类或类实例中填充必要的代码,并依据执行情况返回一个逻辑值,表示,执行是否成功。
至此,针对触发器,我们已经做完了所有基本准备工作。那么,如何来使用它们呢?
我们可以在MyDataEnvironment类的Add自定义方法中使用类似下面的代码(这里仅仅是一个DEMO):
ForEachm.loRelationIn This.Objects
If Upper(m.loRelation.BaseClass) ==[RELATION]
m.llReturn = m.loRelation.Add()
Ifm.llReturn =.F.
Exit
Endif
Endif
Endfor
最后,我们不要忘了MyRelation的本职工作,临时关系。
我们再增加一个MyCursorRelation的自定义方法和一个lRelation的自定义属性。lRelation属性被用于运行时刻标记是否已经设置好游标间的临时关系,所以,其默认值为.F. .
MyCursorRelation的代码:
If!Empty(This.ChildAlias)And;
!Empty(This.ChildOrder)And ;
!Empty(This.ParentAlias)And ;
!Empty(This.RelationalExpr)And ;
This.lRelation =.F.
If Empty(This.RelationalExpr)
This.RelationalExpr= (This.Parent.Parent.Name) +"."+ (This.Parent.Name) +"."+ (This.Name) +"."+"ChildOrder"
EndIf
Select(This.ParentAlias)
Set Relation To(This.RelationalExpr)Into This.ChildAlias In This.ParentAliasAdditive
Set Skip To(This.ChildAlias)
This.lRelation =.T.
Endif
这样,我们就完成了插入触发器和关系的设置。详细的调用方法,后面会予以补充。
这里,我想说明一点:虽然我们的自定义方法命名为InsertTirgger,但是,因为它是在增加记录时使用,所以,当你的数据环境中不需要触发器或者仅有一个Cursor时,它也是非常有用的。尽管我们在MyCursor中会处理记录增加前需要处理的状况,但是,也许,你可能有一些业务逻辑代码需要放置其中以完成你想完成的任务。例如,处理一下和新增记录相关联的一些判断。
如果你不是很懂上面的代码,我建议你按照VFP的经典模式,在数据环境中设置一下游标之间的关系,然后,在属性窗口中查看它的非默认属性值。
你的反馈是我写作的动力,欢迎评论,未完待续。
领取专属 10元无门槛券
私享最新 技术干货