怎样在midas远程数据模块中实现业务规则?请Midas 高手指教! (200分)

  • 主题发起人 主题发起人 zzao
  • 开始时间 开始时间
Z

zzao

Unregistered / Unconfirmed
GUEST, unregistred user!
在应用Midas进行三层应用开发时,我碰到这样的情况,比如,我现在开发一个订单录入
及修改的远程数据模块,可能有这样的业押规则,订单中每个产品的数量都不能为0,为
了在应用服务器上实现这一业务规则,我想在 DataSetProvider 的BeforeUpdateRecord
事件中对 ClientDataSet 传入的数据 DeltaDS 对行检查,看每个产品的数量是否不为
0,如果为0,则不执行保存并通知用户输入数据不符标准,但是我怎样才能在客户端通
知用户输入有错呢?我的想法是,用没有办法根据不同的情况,向客户端传送一个参
数(比如一个提示字符串),让客户端显示这个字符串?
也许我上面使用 BeforeUpdateRecord的方法本来就作不到这一点,请你告诉我怎样在中间
层实现业务规则,并将业务规则的检验结果通知客户端。请写出具体的作法,附实现的代
码。我当不胜感激!
 
赶快回答呀,200大洋!
 
你可以在服务器端的Table上作固定字段,在TField上
实现你的约束,加上违反规则后的提示信息.
然后在由TClientDataset继承服务器段的约束.
 
呵呵,这个问题我也很想知道呀,好像是中间层向客户端传参数,
在TLB中加入方法,参数类型为out,客户端以DComconnection.appserver.方法名 用之
然后我还没试过,呵呵……
 
叶不归的方法不错,我曾经试过。
 
这可在Client端做判断的,写在ClientDataSet的Field中的OnValdate即可
 
To zzao :你在服务端的进行业务规则检查,如果不符合就Raise一个异常。
在各户端的OnUpdatedataErro事件中捕获异常,然后显示出来,再作
相应的处理就可以啦。
 
关注此问题。
 
在业务对象中添加一个方法ApplyUpd,传入数据为客户端cds的delta,业务对象在接受
这个delta的时候就可以判断里面的字段是否为0,如果为0直接返回给客户端一个错误,
如果不为0,调用数据模块中IAppserver的As_ApplyUpdate方法将delta更新到数据库中。
李维的Ado/MTS/COM+高级程序设计书中充满了这种例子,看一下,什么问题都解决了。
 
在中间层的方法调用中加一个返回错误信息的参数返回错误信息,让客户端去处理吧。
 
我个人认为类似这类规则就在客户端完成。
目的是为了减少ROUTINGS 。
 
to anlhy:
不同意你的说法,如果这样规则变化,那就麻烦了。
to davidc
你的想法不错,但是,如果系统中的表多了,又怎么办呢?
对于分布式开发,由于初用,只是一知半解,以后还望各位大富们多多帮助。
 
关注此问题。
 
这和数据库中表有多少完全没有关系,我建议的做法是在中间层分别建立数据对象和业务
对象,数据对象里面分别只有一个TAdoConnectioin、TAdoDataSet和TDataSetProvider,
其中TAdoDataSet连接指定的数据库,而TAdoDataSet不指向任何一张表。向数据库取数据
的事情完全交给业务对象去做,在业务对象中调用IAppserver的As_GetRecord方法,中间
的CommandText参数里面指定向数据库中哪张表取数据。这样必须把AdoDataSet的
AllowCommandText属性设置为True。更新数据的时候可以通过IAppserver的As_Execute
或As_ApplyUpdate方法完成。同样需要在业务对象中定义调用这些方法的函数,然后客户
端只要调用业务对象提供的函数就可以了。如果中间层业务对象的更新数据库方法包含
对多张数据库表的更新,中间层业务对象必须定义为需要事务,这时如果客户端启动时
直接创建业务对象的时候,就会在中间层启动一个事务,这样做是比较浪费资源的,所以
建议再创建一个协调对象,协调对象映射业务对象提供的函数,客户端启动时只创建协调
对象,需要更新数据时在由协调对象去调用业务对象的方法。
 
我非常想知道!
 
Davidc:
能否告知,如何实际的实现企业对象(通过协调对象来调用功能对象),有什么例子或好的学习资料
清提供一些。将万分感谢!
 
李维著作《Delphi 5.x ADO/MTS/COM+高级程序设计篇》。不是作广告,这本书挺好的。
具体例子在6,8,9章都有,不过不是很详细。自己摸索一下应该能实现。
 
感谢davidc的作答。但有如下疑问,如有时间可帮忙看看:
>这和数据库中表有多少完全没有关系,我建议的做法是在中间层分别建立数据对象
>和业务对象,数据对象里面分别只有一个TAdoConnectioin、TAdoDataSet和
>TDataSetProvider,其中TAdoDataSet连接指定的数据库,而DataSet不指向任何一
>张表。
出于学习目的,我将文中提到的业务对象与数据对象合到一起来实现您的想法。
>向数据库取数据的事情完全交给业务对象去做,在业务对象中调用IAppserver的
>As_GetRecords方法,中间的CommandText参数里面指定向数据库中哪张表取数据。
>这样必须把AdoDataSet的AllowCommandText属性设置为True。
在一个mts/com+组件中实现了如下一个方法:
procedure Tjsjsb.GetComputerList(var vData: OleVariant;
const SQLTEXT: WideString);
var
Options: TGetRecordOptions;
iRecout: Integer;
OwnerData: OleVariant;
Params: OleVariant;
begin
try
Options := [grMetaData, grReset];
vData := As_GetRecords('dspPublic', -1, iReCout, Byte(Options),
SQLText, Params, OwnerData);
SetComplete;
except
SetAbort;
end;
end;

我的问题是:客户端在接受到返回的结果,如何做录入界面与之配合呢?比如
我用dbgrid来处理,那么每字段的Caption怎么解决?
另,上面提到的AllowCommandText,实际是指
DataSetprovider.Options.poAllowCommandText:=True.
>更新数据的时候可以通过IAppserver的As_Execute或As_ApplyUpdate方法完成。
一时间想不出办法如何封装As_Execute或As_ApplyUpdate,只是客户端做了如下
的测试代码
dcomConnection1.Appserver.As_ApplyUpdates('dspPublic',
clientdataset1.Delta, 0,i,'select * from jsj_mxb');
从代码中,可看到必须向com+组件中的DataSetProvider发出'select * from
jsj_mxb',然后在DataSetProvider的beforeApplyUpdates事件中处理,将SQL语句
复制给ADODataSet.commandText.只有这样,客户端的修改才能正确更新回数据库。
对于这样的处理方法,是否有更好的方法来解决?
>同样需要在业务对象中定义调用这些方法的函数,然后客户端只要调用业务对象提
>供的函数就可以了。如果中间层业务对象的更新数据库方法包含对多张数据库表的
>更新,中间层业务对象必须定义为需要事务,这时如果客户端启动时直接创建业务
>对象的时候,就会在中间层启动一个事务,这样做是比较浪费资源的,所以建议再
>创建一个协调对象,协调对象映射业务对象提供的函数,客户端启动时只创建协调
>对象,需要更新数据时在由协调对象去调用业务对象的方法。
关于上面这段,一时更是不知如何处理,能否明示?
 
后退
顶部