DA17 - Data Abstract 3.0新特性

By | 04月24日
Advertisement

DA17 - Data Abstract 3.0新特性DA17 - Data Abstract 3.0新特性

导论

Data Abstract 3.0 引入了一系列新特性将改善数据接口以及创建数据驱动中间层的方式. 本文提供产品的综述和并认识其新特性.

内容

  • 新的DAServer
  • 改进的DARemoteService
  • 增强动态方法绑定
  • 更新规则
  • Schema Modeler图解
  • 关系和改进的Autoinc支持
  • Automatic同步
  • DALoginService
  • 脚本支持
  • XMLDataAdapter
  • 新的查询生成器
  • 增强的连接向导
  • 新的MiniWH 范例
  • 其他
  • 总结

注意:
一些图被缩小了如果看不清楚可点击放大.

新的DAServer

Data Abstract 3中提供的DAServer是一个可执行的standalone服务.

DAServer (简称DAS)可以standalone应用程序或NT服务方式运行并基本上提供你需要的完整的Schema多层服务.

如果你只想生成一个多层应用查询数据,DAServer将为你提供一个清晰完整的夸数据库风格的解决方案. DAServer, 结合新的脚本功能允许你不用写中间层代码创建一个及其动态的系统,除非你要那样做.

当你以standalone方式启动DAS应用程序(DAServer.exe),如下图:

DA17 - Data Abstract 3.0新特性

在上面的截图,已经注册了一个基于MSSQL的Northwind数据库的Schema.关于更多DAServer的信息点击DA15.

改进的DARemoteService

Data Abstract的DARemoteService为开发者提供很多开发数据驱动服务的基础功能. 为你实现了诸如GetSchema, GetDatasetData, UpdateData等方法使你可直接使用查询服务端的数据集定义,实际数据和更新等操作.

在Data Abstract 3,极大的增强了IDARemoteService 接口并提供了一些附加方式使其更简单,同时保留100%的向后兼容性.

新方法如下:

  • GetDatasetDataEx
  • ExecuteSQLCommandEx
  • GetMultipleDatasets
  • GetDatasetScripts

GetDatasetDataEx

function TDARemoteService.GetDatasetDataEx(const DatasetName: String;

const Params: TDADatasetParamArray;

const UserFilter: String;

const IncludeSchema: Boolean;

const MaxRecords: Integer): Binary;

var parnames : array of string;

parvalues : array of variant;

i : integer;

options : TDAWriteOptions;

begin

result := Binary.Create;

try

{ Prepares the parameter arrays}

SetLength(parnames, Params.Count);

SetLength(parvalues, Params.Count);

for i := 0 to (Params.Count-1) do begin

parnames[i] := Params[i].Name;

parvalues[i] := Params[i].Value;

end;

{ Other options }

if IncludeSchema

then options := [woSchema, woRows]

else options := [woRows];

{ Reads the data }

DoGetDatasetData(

result, Connection, DatasetName, parnames,

parvalues, UserFilter, ServiceSchema, ServiceAdapter,

options, MaxRecords);

except

FreeAndNIL(result);

raise;

end;

end;

像原来的GetDatasetData方法,这个方法仍然允许你打开远程数据集的定义信息,但是替换掉必须强制提供固定参数名称和参数值的方式,改为TDADatasetParam数组.

TDADatasetParam声明如下:

{ TDADatasetParam }

TDADatasetParam = class(TROComplexType)

[..]

published

property Name:String read fName write fName;

property Value:Variant read fValue write fValue;

end

值得注意的是,如果现在你设置DataTable的Params值将自动映射到GetDatasetDataEx方法 Params 参数, 除非你明确的设置了他们.DataTable引入了一个新的属性: MaxRecords. 如果你对这个属性设置了一个值,讲自动映射到GetDatasetDataEx方法的 MaxRecords参数.
最后,DataTable的Where属性将映射到UserFilter参数.

看如下代码:

procedure TClientForm.bbManualParametersAssignmentSearchClick(

Sender: TObject);

var myparams : TDADatasetParamArray;

begin

myparams := TDADatasetParamArray.Create;

with ClientDataModule.dtProducts do try

Close;

with myparams.Add do begin

Name := 'Name';

Value := eProductName.Text;

end;

with myparams.Add do begin

Name := 'BuyPrice';

Value := StrToFloat(eMaxPrice.Text);

end;

DataRequestCall.ParamByName(par_DatasetName).AsString :=

LogicalName;

DataRequestCall.ParamByName(par_Params).AsComplexType := myparams;

DataRequestCall.ParamByName(par_UserFilter).AsString := '';

DataRequestCall.ParamByName(par_MaxRecords).AsInteger :=

seMaxProducs.Value;

DataRequestCall.ParamByName(par_IncludeSchema).AsBoolean := FALSE;

DataRequestCall.ParamByName(par_MaxRecords).AsInteger :=

seMaxProducs.Value;

Open;

finally

myparams.Free;

// Clears the reference to the garbage pointer

DataRequestCall.ParamByName(par_Params).Clear;

end;

end;

bbManualParametersAssignmentSearchClickManual Parameters Assignment按钮的事件处理函数,如下图:

DA17 - Data Abstract 3.0新特性

附加的UserFilter参数允许你传递一个Where 条件选项,在客户端生成复杂的数据集筛选条件用于数据集表达式. UserFilter属性支持特殊的字段名前缀("##")指明这个客户端使用的字段名已经通过的服务端数据集表达式的ColumnMapping提换过.

看如下代码:

procedure TClientForm.bbSearchUsingUserFilterClick(Sender: TObject);

begin

with ClientDataModule.dtCustomers do begin

Close;

// Prepares the custom WHERE clause

Where.Clear;

Where.AddConditions(['CustomerIdx','FirstName','LastName','City'],

[cEqual,cLike,cLike,cLike],

[eCode.Text,eFirstName.Text,eLastName.Text,

eCity.Text], opAnd);

if Where.Empty

then stWhereClause.Caption := msg_NoCondition

else stWhereClause.Caption := Where.Clause;

MaxRecords := seMaxCustomers.Value;

{ The above is equivalent to:

DataRequestCall.ParamByName(par_UserFilter).AsString:=Where.Clause;

DataRequestCall.ParamByName(par_MaxRecords).AsInteger :=

seMaxRecords.Value;

Note: par_UserFilter and par_MaxRecords are constants defined

in uDADataTable.pas

}

Open;

end;

end;

bbSearchUsingUserFilterClickSearch 按钮的事件处理函数,如下图:

DA17 - Data Abstract 3.0新特性

注意:上图中间部分的状态行(grid上方)显示了当前筛选字符串(stWhereClause.Caption) ,其中显示了前面讨论的’##’前缀. 考虑一下需要的代码-虽然我们没有使用所有的筛选条件,这里没有出现乏味的SQL命令代码.

ExecuteSQLCommandEx

function ExecuteSQLCommandEx(const CommandName: String;

const Params: TDADatasetParamArray): Integer;

var cmd : IDASQLCommand;

i : integer;

begin

if not AllowExecuteSQLCommand then

RaiseError(err_ExecuteSQLCommandNotAllowed);

CheckObjects(Connection, ServiceSchema, NIL, TRUE, TRUE, FALSE);

cmd := ServiceSchema.NewCommand(Connection, CommandName);

for i := 0 to (Params.Count-1) do

cmd.ParamByName(Params[i].Name).Value := Params[i].Value;

if Assigned(fOnBeforeExecuteCommand)

then fOnBeforeExecuteCommand(Self, cmd);

result := cmd.Execute;

if Assigned(fOnAfterExecuteCommand)

then fOnAfterExecuteCommand(Self, cmd, result);

end;

ExecuteSQLCommandEx扩展了原来的ExecuteCommand方法,允许你通过Params参数传递执行存储在服务端的Schema中的命令.

ExecuteSQLCommandEx通过引用命令名称运行,这些命令在不同的数据库有不同的表达式,你应确信命令将透明的在不同的数据库上执行,而客户端并不知道.

GetMultipleDatasets

function TDARemoteService.GetMultipleDatasets(

const DatasetRequestInfoArray: TDADatasetRequestInfoArray)

: TROBinaryMemoryStream;

var i : integer;

ds : IDADataset;

parnames : array of string;

parvalues : array of variant;

x : integer;

opt : TDAWriteOptionS;

begin

result := NIL;

if (DatasetRequestInfoArray=NIL) or (DatasetRequestInfoArray.Count=0)

then Exit

else result := Binary.Create;

ServiceAdapter.Initialize(result, aiWrite);

try

for i := 0 to (DatasetRequestInfoArray.Count-1) do

with DatasetRequestInfoArray[i] do begin

SetLength(parnames, Params.Count);

SetLength(parvalues, Params.Count);

for x := 0 to (Params.Count-1) do begin

parnames[x] := Params[x].Name;

parvalues[x] := Params[x].Value;

end;

opt := [woRows];

if DatasetRequestInfoArray[i].IncludeSchema then

opt := opt+[woSchema];

ds := ServiceSchema.NewDataset(

Connection, DatasetName, parnames, parvalues, TRUE);

ServiceAdapter.WriteDataset(ds, opt, MaxRecords);

end;

ServiceAdapter.Finalize;

except

FreeAndNIL(result);

raise

end;

end;

这个函数在单个网络通讯中返回多个数据集从而优化响应时间. DatasetRequestInfoArray参数运行你指定你要传递数据的数据集及其参数(如果确实需要). TDADatasetRequestInfo 声明如下:

{ TDADatasetRequestInfo }

TDADatasetRequestInfo = class(TROComplexType)

[..]

published

property DatasetName:String read fDatasetName write fDatasetName;

property IncludeSchema:Boolean read fIncludeSchema

write fIncludeSchema;

property MaxRecords:Integer read fMaxRecords write fMaxRecords;

property Params:TDADatasetParamArray read GetParams write fParams;

end;

The following code is taken from the new GetMultipleDatasets sample:

procedure TClientForm.bbGetDatasetsClick(Sender: TObject);

var datasets : TDADatasetRequestInfoArray;

datasetinfo : TDADatasetRequestInfo;

begin

{

The following code shows how to manually create this type of request

using TDADatasetRequestInfo and TDADatasetRequestInfoArray objects.

This type of code is useful when you want to control the parameters

of each TDADatasetRequestInfo element.

Keep in mind that the two datasets can actually be opened at design

time by using the property values set in this demo.

}

datasets := TDADatasetRequestInfoArray.Create;

with ClientDataModule do try

dtCustomers.Close;

with datasets.Add do begin

DatasetName := 'Customers';

MaxRecords := -1;

IncludeSchema := FALSE;

end;

{ NewDatasetRequestInfo is a utility function contained in

uDAInterfaces.pas }

NewDatasetRequestInfo(datasets, 'Orders', [], [], FALSE, -1);

dtCustomers.DataRequestCall.ParamByName(

par_DatasetRequestInfoArray).AsComplexType := datasets;

dtCustomers.Open;

finally

datasets.Free;

// Cleans garbage pointers

dtCustomers.DataRequestCall.ParamByName(

par_DatasetRequestInfoArray).Clear;

end;

end;

这里一个重点是数据集传输到客户端发生在运行时.

GetDatasetScripts

function GetDatasetScripts(const DatasetNames: String): String;

这个函数返回有DatasetNames参数指定的用逗号分隔的多个数据集列表的业务脚本.Data Abstract业务脚本详细信息及支持请见DA16.

这个功能提供了简单的方式在运行时下载新的脚本(例如,当你应用程序启动并第一次连接到远程服务).

procedure TProductSearchForm.bbSearchClick(Sender: TObject);

begin

with ClientDataModule.dtProductsSearch do begin

Close;

// Prepares the custom WHERE clause

Where.Clear;

Where.AddConditions(

[fld_ProductsSearchProductName,fld_ProductsSearchProductGroupName,

fld_ProductsSearchSellPrice, fld_ProductsSearchAvailQty],

[cLike, cLike, cLessOrEqual, cMajorOrEqual],

[eName.Text, cbProductGroups.Text,

StrToFloatDef(eMaxPrice.Text, MillionBucks),

StrToIntDef(eQuantity.Text, 0)],

opAnd);

if Where.Empty

then stWhereClause.Caption := msg_NoCondition

else stWhereClause.Caption := Where.Clause;

// Fetches the records

MaxRecords := seMaxRecords.Value;

Open;

AdjustForm(Self);

end;

end;

增强的动态方法绑定

动态方法绑定(DMB)可能是Data Abstract架构最强大的特性.本文假设你已经阅读并理解描述其详细功能的文档DA04.这里只说一下Data Abstract 3中增强的部分.

今年我们收到很多请求增强或简化DMB.对来自客户端/服务器的用户,不能自然的分开思考方法参数和查询参数.

例如,你定义了一个查询:

SELECT * FROM Customers WHERE Name LIKE :Name

很多用户感到很惊讶,当调用Schema向导加载数据集时没有从DataRequestCall结构体中找到"Name"参数.另外一些人注意到如何将DataTable的Params属性映射到"Name",如果其值在调用Open前被赋予,将不能向中间层传递.

相关的其他话题使用有个细表数据集:细表数据集的属性MasterRequestMappings指定主表字段值作为远程方法的参数用于获取子表数据集.例如,假设你有一个主表Customers数据集以及连接的Orders数据集,为了在Customres数据集滚动时获取Orders记录,你需要如下方法:

function GetOrders(CustomerIdx: integer) : Binary

begin

result := GetDatasetData(fConnection, 'Orders',

['CustomerIdx'], [CustomerIdx]);

end;

Data Abstract 3 不再需要你去做这些了. DataTables现在提供了两中master mapping模式:

1) mmDataRequest

这是最初的映射方式,将主表的字段值关联到一个远程方法的参数.当你的主表游标滚动,细表数据集将调用如上面的GetOrders远程方法,并使用主表的字段值填充参数.这种映射为远程数据获取提供了最大的控制和灵活性.

2) mmParams

现在在Data Abstract 3,在服务端的Schema中定义连接到主表数据集字段值的远程数据集参数.简单的使用新的GetDatasetDataEx方法作为DataRequestCall方法,当主表数据集滚动,GetDatasetDataEx的Params参数将自动赋值而且远程查询的参数将不需要任何自定义方法而自动设置.这种映射取消创建像GetOrders这样的客户自定义方法,除非你实际应用中确实需要自己控制打开数据集.

下面截图展示Orders DataTable的设置:

DA17 - Data Abstract 3.0新特性

另外,主细表组件编辑器已经改进允许你定义新类型映射:

DA17 - Data Abstract 3.0新特性

其他对DMB的增强是有一个新的MasterOptions/DetailOptions 属性以及 IncludeInAllInOneFetch.假设你有一个方法要一次获取Customers和Orders表,但是不需要传递OrderDetails,这个新的枚举值将指示服务端的OrderDetails数据集不去查询数据并加入到流中. 所以在假设的情形下,你应该将Customers和Orders一次性获取,而OrderDetails在要求时获取(如Orders滚动).这种组合很多.

更新规则

Data Abstract 2包含一个叫做BasicDADemo的范例.其中展示如何做一些稍微复杂的操作,如控制Delta更新的顺序,使用DMB获取数据等.这些都相对简单.

其他文档中已经说明当同时发送Customers,Orders和OrderDetails时如何控制更新顺序,而且完全控制所有事情.不幸的是这些都需要写代码.

接下来我们打算重写BasicDASample展示如何在Data Abstract 3中不写代码做到这些!

Data Abstract 3引入了更新规则的概念,允许你指定服务端处理Delta更新的属性.

如果你看DA10文档-深入业务处理器,将看到如何写代码实现.

如下截图将可视化的向你演示如何使用新的Schema Modeler和Data Abstract 3实现:

DA17 - Data Abstract 3.0新特性

如果你在Schema中定义了一个更新规则, DARemoteService.UpdateData方法将按照特定的顺序处理Delta(注意up/down按钮)而且在一些特定的步骤中只应用适当的更新类型.如果你孤立的看可以发现Delete顺序和Insert的顺序不同.考虑到主细表关系中引用完整性约束,主表必须先于细表插入而细表必须先于主表删除.通过使用Data Abstract 3的这个新特性,你可以定义一个非常复杂的更新情形而不用写一行代码,同时你在服务端存储这些更新规则信息. 这很重要,可以在服务端修改更新规则而不需要变动客户端.

Schema Modeler 图表

Data Abstract 3引入了一个期待很久的特性:图表.

DA17 - Data Abstract 3.0新特性

Data Abstract 3同时也引入了一个新的TDADiagrams组件,拖放后与你的Schema相连- 如果你启动SM并创建图表,图表信息将存储在TDADiagrams组件中最终存放在dfm文件.

Schema Modeler只有在启动或者点击的TDASchema已经指定TDADiagrams组件时候才能获取图表支持.

你可以在DA14中查看更多图表信息.

关系和改善的AutoInc支持

当你在Schema中创建两个表的关系时,将在Schema中创建相应的关系实体并保存在其中.

例如,假如有如下图表:

DA17 - Data Abstract 3.0新特性

你有如下关系实体:

DA17 - Data Abstract 3.0新特性

关系向DARemoteService提供帮助解决基于autoinc字段更新的信息,例如在MiniWH范例中的Customers,Orders,OrderDetails.这些表的主键值是自动增加的.

当你在客户端插入一条新的Customers信息时,CustomerIDx字段的值默认为一个负数 (例如 -1).

每个关联到这个新的Customers的Order的CustomerIdx字段都等于-1而OrderIdx将也是一些负数 (例如-1, -2 和-3假设我们增加了3个订单). OrderDetails应用同样逻辑.

为解决这些更新,在Data Abstract 2中要求在代码中自定义方法如DA10中的UpdateThreeLevels方法并要实现业务处理器的事件如 OnAfterProcessChange等.理由很简单:一旦一个新的Customers增加到数据库,CustomerIdx值将从-1变为一个新数字(如1233)以及所有与之关联的Order记录的CustomerIdx字段的值也要从-1变为1233.

由于Schema关系(Relationship),现在将自动进行而不再需要象以前一样写复杂更新方法的代码了!

Data Abstract 3 也考虑到不同数据库(Interbase Microsoft SQL Server)的差异. Interbase (或Oracle)不支持autoInc字段而是要使用与autoInc字段不同的生成器(Generator).当你使用生成器,在提交记录前必须告诉数据库下一个值,相比较而言autoInc字段则是在你提交记录后读取最后生成的值. Data Abstract 3自动的处理这种差异,使用生成器的DA连接已经被更新.为了实现这个目标向特定的驱动加入一个新接口:

{ IDAUseGenerators }

IDAUseGenerators = interface

['{7963D550-361E-486A-AAD6-EFD12896F719}']

function GetNextAutoinc(

const GeneratorName: string): integer; safecall;

end;

例如, Interbase Express, ODAC 和IBObjects支持这个新的接口,业务处理器在读取autoInc值时首先判断连接是否支持这个接口.

另外,DA字段增加了一个新的属性指明用于获取下一个基于生成器的autoInc字段值的生成器.下图显示了这个新属性:

DA17 - Data Abstract 3.0新特性

在MSSQL数据库的Order表中不需要使用这个属性.而对以Interbase数据库,使用这个属性在记录提交到DB后自动调用IDAUseGenerators.GetNextAutoinc.

自动生成字段同步

Autoinc 字段,数据库触发器或客户定义的服务端方法都可能在Delta应用之前或之后修改Delta.例如,假设Order表中的TotalPrice字段需要在记录提交到数据库前在服务端计算.如果这样,客户端或者要重新获取这个数据集实体或者在数据库中读取新值后将之返回到客户端. 然而在Data Abstract 2中必须要写代码实现 (见DA10 中的例子),在Data Abstract 3中则不在需要了.

数据集的字段已经被一个新的ServerAutoRefresh属性扩展,指示远程服务在记录提交后重新读取行并将新值发送回客户端.例如,我们设置Orders.TotalPrice的ServerAutoRefresh 属性为TRUE,在记录提交以后服务将自动发出一个SELECT TotalPrice FROM Orders WHERE [..]查询. 更新查询中只包含标记为ServerAutoRefresh的字段以便于提高执行效率.

因而如果你的数据集字段被触发器,业务代码或其他过程修改,只需要设置这个属性为TRUE, 不需要写代码你的DataTable将在单一的网络往返中自动自我更新!

DALoginService

多数系统都需要一个窗体做用户登陆. 基于此Data Abstract 3引入一个新的同DARemoteService的使用方式一样的基础服务.这个基础服务叫做DALoginService并定义如下:

{ IDALoginService }

IDALoginService = interface(IDARemoteService)

['{58550AA0-B64F-495A-B2F8-C981D4C39180}']

function Login(const UserID: String;

const Password: String; out LoginInfo: TDALoginInfo): Boolean;

procedure Logout;

end;

Login 获取UserID 和 Password 参数并使用它们生成一个查询如

SELECT * FROM Users WHERE UserID=:UserID AND UserPassword=:UserPassword

如果查询返回一个单一记录登陆成功,返回TRUE并生成一个如下声明的TDALoginInfo 结构:

{ TDALoginInfo }

TDALoginInfo = class(TROComplexType)

[..]

published

property SessionID:String read fSessionID write fSessionID;

property UserID:String read fUserID write fUserID;

property Privileges:TDAStringArray read GetPrivileges

write fPrivileges;

property Attributes:TDAStringArray read GetAttributes

write fAttributes;

property Data:Binary read GetData write fData;

end;

像SessionID和UserID属性将自动填充,你可以选择使用这些剩余的参数向客户端返回自定义的值.

更多关于登陆处理的解释将在说明MiniWH的文档中推出,但是现在值得看一下DALoginService数据模块的一些属性:

DA17 - Data Abstract 3.0新特性

LoginDataset属性允许你指定哪个Schema的数据集去验证UserID 和Password.

ParamNameUserIDParamNamePassword允许你指定要接收UserID和Password值得参数名字.

可选的 LogoutCommandParamNameSessionID 属性指示当Logout执行时DALoginService自动执行一个特殊的SQL命令,这个SQL命令期望使用SessionID(字符串)参数.

OnLogin, OnLoginFailure, OnLoginSuccessOnLogout事件允许你在登陆过程的各个阶段自定义服务行为.例如,假设你的客户端发送UserID和Password,但是你在数据库存储的是加密格式,这时可以在OnLogin事件中作如下处理:

procedure TLoginService.DALoginServiceLogin(Sender: TDALoginService;

var aUserID, aPassword: String);

begin

aPassword := EncryptPassword(aPassword);

aUser := UpperCase(aUser);

end;

这个事件执行后,将为LoginDataset属性指定的数据集提供新的UserID和password参数值然后打开这个登陆数据集作具体验证.

脚本支持

脚本在DA16中详细介绍.

业务规则脚本提供了一种解决方案,可以集中的在Schema中同数据一起定义客户端业务规则.你可以继续使用熟悉的Pascal代码写业务规则而且这些规则将自动传送到客户端并在客户端执行. 当业务规则需要变化只需在Schema中修改,客户端使用DARemoteService.GetScripts 方法获取新的业务规则.

新的DAServer允许你传递脚本而且这两种工具在一起运行良好.

XMLDataAdapter

Data Abstract 3引入期望已久的返回平台无关的数据的XML Adapter.

注意:在3.01版本,XMLAdapter还不完整但是计划在后面版本中更新.

点击TDAXMLAdapter控件,可以在属性编辑器中看到如下属性:

DA17 - Data Abstract 3.0新特性

TDAXMLAdapter输出如下所示的XML格式:

<XMLData>

<Schema>

<Datasets>

<Customers>

<Fields>

<Field Alignment="taLeftJustify" BlobType="dabtUnknown"

BusinessRulesID="" Calculated="False"

CustomAttributes="10772264" DataType="datAutoInc"

DefaultValue="" Description="" DictionaryEntry=""

DisplayFormat="" DisplayLabel="CustomerIdx"

DisplayWidth="0" EditFormat="" EditMask=""

GeneratorName="CUSTOMERIDXGEN" InPrimaryKey="True"

KeyFields="" LogChanges="True" Lookup="False"

LookupCache="False" LookupKeyFields=""

LookupResultField="" LookupSource="0"

Name="CustomerIdx" ReadOnly="False" RegExpression=""

Required="True" ServerAutoRefresh="True"

Size="0" SqlOrigin="CustomerIdx" Visible="True" />

</Fields>

</Customers>

</Datasets>

</Schema>

<Data>

<Customers>

<Row CustomerIdx="50" FirstName="Amity" LastName="Nappier"

Address1="4754 Dominion Street" City="Rollinsford"

State="PR" Zip="35295" Phone1="(247) 891-9858"

Email="[email protected]"

CreditCard="5981417510866867" />

</Customers>

</Data>

</XMLData>

通过SchemaOptions.soIncludeAllAttributes属性值可以控制是否包含字段定义,而 RowOptions.roCompressBlobs 属性控制是否在编码前压缩blob数据.

IncomingXSLTOutgoingXSLT 属性允许你对各自的XML流做应用XSLT转换.例如,如果你从.NET web service中接收一个ADO.Net的Dataset,你应该使用IncomingXSLT 属性指定XSLT文件映射到Data Abstract格式.当将数据集返回时需要使用OutgoingXSLT属性指定相反的转换.

查看压缩文件(见本文上面的连接)中的Customers.xml文件. 其中包含了从MiniWH范例中抽取的Customers例子而且还有一个可以将Customers.XML转换为HTML的XSLT文件.

XML Adapter通常用于为外部系统提供接口的情况.到ADO.NET的映射将在下一个版本中提供,这样就可以在Win32和.NET或Pocket PC(CF)之间传递数据了.

新的查询生成器

Schema Modeler中新的Build Query工具栏按钮提供了一个可以轻松实现JOINs或复杂WHERE子句的查询生成器:

DA17 - Data Abstract 3.0新特性

通过Data Abstract 3提供的增强主外键元数据支持是自动连接查询成为可能. 更多信息请看DA14.

增强的连接向导

生成一个初始的连接过程是不同的,不幸的是这是第一个要做的工作. Data Abstract 3 提供了一个动态帮助面板显示特定数据库连接信息.注意这两个截图的不同:

DA17 - Data Abstract 3.0新特性

DA17 - Data Abstract 3.0新特性

帮助面板将在后面的版本中有所变动,你可以从FAQ37 获取最新信息.

新的MiniWH 范例

MiniWH 范例(mini warehouse) 需要独立安装,其中包含可执行的服务端和客户端执行以及需要的数据库文件.提供了如下终端数据库版本支持:

  • Microsoft SQL Server 2000
  • FireBird 1.5
  • DBISAM 4
  • Oracle
  • Sybase

DA17 - Data Abstract 3.0新特性

范例将使连接到多个数据库终端很简单,而且向你展示如果做到很酷的效果(包括很好的N层设计模式). 计划生成一个文档说明这个范例. 你可以点击here查看,但是请记住这是一个循序渐进的工作一些小节将会变动或删除.

其他

其他增强包括:

  • DARemoteService.AutoCreateBusinessProcessors 属性:由于这个属性你不比再为每个要更新的数据集拖放一个TDABusinessProcessor了. Data Abstract 3中如果你要用代码指定特殊的业务逻辑只需要拖放一个业务处理器组件.其他时候将自动为你处理.
  • DARemoteService.AllowExecuteSQLCommand: 这个属性允许你阻止恶意用户远程调用ExecuteSQLCommand执行SQL命令. 注意:这个特性不是最终版可能在以后版本中扩展改进.
  • DADesignTimeCall 组件: 拖放它到客户端窗体可以帮助测试,设置其RemoteServiceRemoteRequest.MethodName 属性就可以在设计时执行远程查询.在DA15中查看”在客户端存取DAServer”的更多信息.

总结

本文对Data Abstract 3.0的新特性和增强支持提供了简短的讨论.

重点包括:

  • DAServer: 新的standalone可执行服务 (DA15)
  • 改进的 DARemoteService: 附加方法- GetDatasetDataEx, ExecuteSQLCommandEx, GetMultipleDatasets 和 GetDatasetScripts
  • 增强了TDAWhere ColumnMappings: 更有效率的生成夸数据库解决方案
  • 动态方法绑定的增强:使用新的GetDatasetDataEx 调用减少自定义方法
  • 更新规则:不用代码就可以控制主细表更新顺序
  • Schema Modeler 图表:通过拖放生成数据集及其关系(article DA14)
  • Relationships 和改进的Autoinc支持:使用关系提供的支持可以不用写代码处理自动增加字段的autoInc和Generator问题
  • Automatic 字段同步:服务端的值变化可以自动的反映到客户端
  • DALoginService: 不需要代码就可以使用扩展的login/logout
  • 脚本支持:允许客户端执行存放在服务端的业务规则
  • XML Data Adapter: better connectivity with external systems
  • 新的查询生成器
  • 增强的连接向导:新的帮助面板
  • 新的MiniWH 范例:展示如果使用DA的一些特性

从上面的列表中可见,我们主要的设计目标就是减少处理日常数据关系和多层问题的代码量.

请关注下一篇文档"使用MiniWH范例".其中包含了上面提到的所有方面,提供了对使用Data Abstract有用的概述.

Similar Posts:

  • Java(02)-JDK 5.0 新特性

    1.JDK 5.0 新特性 ·泛型 特点: ·很好的解决了集合中对象很难管理其类型的难题. ·List<String> l = new Arraylist<String>() ; ·List < ? extends Number > 表示可以是Number类和其子类 ·List < ? super Number > 表示可以使Number类和其父类 说明: ·在方法参数中使用通配符 ·在方法的参数类型和返回类型中使用通用类型,通用类型是指不指定参数或者返回值

  • 返璞归真 asp.net mvc (10) - asp.net mvc 4.0 新特性之 Web API

    原文:返璞归真 asp.net mvc (10) - asp.net mvc 4.0 新特性之 Web API [索引页] [源码下载] 返璞归真 asp.net mvc (10) - asp.net mvc 4.0 新特性之 Web API 作者:webabcd 介绍 asp.net mvc 之 asp.net mvc 4.0 新特性之 Web API 开发一个 CRUD 的 Demo,服务端用 Web API,并使其支持 jsonp 协议,客户端用 jQuery 示例 1.自定义一个 Jso

  • ASP.NET Web API 2.0新特性:Attribute Routing1

    ASP.NET Web API 2.0新特性:Attribute Routing[上篇] 对于一个针对ASP.NET Web API的调用请求来说,请求的URL和对应的HTTP方法的组合最终决定了目标HttpController的类型和定义其中的目标Action方法.两者之间的映射是通过URL路由来完成的,ASP.NET Web API路由系统提供了一种便捷的方式使我们可以在统一的地方注册适用于所有HttpController的路由. 如果我们能够直接针对目标Action方法进行路由注册,那么我

  • 5.0新特性:

    5.0新特性: 前提: 1. JVM没有变, 编译器改变 2. 逐渐和C++融合接近(很多开始被遗弃的C++元素又被捡了回来) 3. 程序员开发越发的简单了 5小点: 1 自动封装和自动解封(简单类型和封装类型之间),但只是在必要的时候进行,比如向上就近原则中public static void method(Byte b){}:调用这个方法的时候不会像上就近调用int,而是直接调用这个方法. Integer i = 3 // OK 封箱 int i = new Integer(3) // OK

  • [WCF 4.0新特性] 路由服务[原理篇]

    在一个典型的服务调用场景中,具有两个基本的角色,即服务的消费者和服务的提供者.从消息交换的角度讲前者一般是消息的最初发送者,而后者则是消息的最终接收者.在很多情况下,由于网络环境的局限,消息的最初发送者和最终接收者不能直接进行消息交换,这就需要一个辅助实现消息路由的中介服务,这就是我们接下来要介绍的路由服务. 目录 一.路由服务就是一个WCF服务 路由服务契约的定义 路由服务契约的定义 二.基于消息内容的路由策略 RoutingBehavior服务行为 消息筛选器 筛选器表 一.路由服务就是一个

  • 分析 C# 2.0 新特性 -- 范型(Generics)

    分析 C# 2.0 新特性 -- 范型(Generics) 作者:梁振[MS-MVP] 范型是提高面向对象程序多态性设计衍生的. 1,C# 多态性设计回顾和展望 在引入范型这个概念之前,回顾一下1.0或1.1中关于的Object类型的定义: Object类型是.NET Framework中System.Object的一个别名,可以分配任何类型给Object类型的变量. 通过object类型的引入,实现了.NET对于面向对象程序多态设计. 因为Object本身是一个引用类型,是存放在Heap(堆)

  • C#3.0新特性:扩展方法初探

    C#3.0新特性:扩展方法初探 C#3.0中一个激动人心的特性就是扩展方法:你可以使用实例方法的语法来调用静态方法.本文仔细阐述了这一新特性并且给出了几个相应的例子. 声明扩展方法 扩展方法的行为和静态方法是非常类似的,你只能在静态类中声明它们.为声明一个扩展方法,你需要给该方法的第一个参数指定this关键字,如下例: // Program.cs public static class EMClass { public static int ToInt32Ext(this string s) {

  • 《Java5.0新特性》 枚举、泛型、注释 包装类、静态应用、可变长参数、for-each

    <Java5.0新特性>四大点(枚举.泛型.注释...):5 小点(包装类.静态应用.可变长参数.for-each...)一.自动装箱 和 自动解箱技术装箱Autoboxing,也翻译作 封箱:解箱Unautoboxing(也译作 解封)1.自动装箱技术:编译器会自动将简单类型转换成封装类型.2.编译器会自动将封装类型转换成简单类型3.注意:自动装箱和自动解箱只会在必要的情况下执行.int 能隐式提升成 long:但Integer不能隐式提升成Long,只能提升成Number封装之后就成类,只

  • VB9.0新特性之LINQ(二) - 常用关键字

    在VB9.0新特性之LNIQ(一)中,我们了解到了LINQ查询的三个关键步骤.LINQ查询好比是一顿丰盛的晚餐:买菜(确定数据源).做菜(创建查询).进餐(执行查询).毋庸置疑,做菜做得怎么样,直接决定进餐的质量.而LINQ的关键字就像是做菜时候的油盐酱醋--道道菜单少不了,不同的菜还要不同的组合下不同的量. 题外扯一句:写惯SQL语句的人一提及查询,就必然想到SELECT……在LINQ中,SELECT不是必须的,而且,它也往往出现在查询语句的结尾部分.谁让现代人都流行把SQL倒着写呢 :-)

  • [转载]Windows Phone SDK 8.0新特性(翻译)

    随笔- 6 文章- 0 评论- 30 Windows Phone SDK 8.0新特性(翻译) 原文地址:What's new in Windows Phone SDK 8.0 欢迎使用Windows Phone SDK 8.0.Windows Phone 8为开发人员提供了一些新特性和升级特性.包括本地代码的游戏开发,手机版的Windows Runtime,以及新的内核.我们把这些介绍都集中在一起,以方便您熟悉Windows Phone 8和Windows Phone SDK 8.0的这些特性

Tags: