延迟取出用户定义类型的指定成员的系统和方法

文档序号:6621664阅读:385来源:国知局

专利名称::延迟取出用户定义类型的指定成员的系统和方法
技术领域
:本发明涉及数据检索和处理的领域,尤其涉及用户定义类型的检索和处理。
背景技术
:微软的SQLSERVER是全面的数据库管理平台,它提供广泛的管理和开发工具,强大的提取、转换、和加载(ETL)工具,商业智能化分析服务,和其它能力,最近对SQLSERVER已实现了两项改进。首先,微软的Windows.NFFrameworkCommonLanguageRuntime(CLR)已经集成到SQLSERVER数据库中,其次,称为用户定义类型(UserDefinedType-UDT)的新对象现在能用CLR环境中管理的代码创建,并保持在数据库存储中。CRL是微软.NET架构的核心,并提供对所有.NET代码的执行环境。因此,在CLR中运行的代码称为“受管代码”。CLR为程序执行提供所需的各种功能和服务,包括即时(just-time-JIT)编译、分配和管理存储器,实施类型安全,例外处理,线程管理和安全性。现在CLR由SQLSERVER在第一次引用.NET例程时加载。在SQLSERVER的以前版本中,数据库编程员在服务器端写代码时被限于使用Transact-SQL。Transact-SQL是由国际标准化组织(ISO)和美国国家标准协会(ANST)规定的用户定义的查询语言的扩展。使用Transact-SQL,数据库开发者能创建、修改和删除数据库和表,并插入、检索、修改和删除存储在数据库中的数据。Transact-SQL是专门为直接结构数据的访问和处理设计的。虽然Transact-SQL在数据访问及管理方面胜出,但它不象VisualBasic.NET和C#是完全成熟的编程语言。例如Transact-SQL不支持对每个循环的数组、集合,位移位或类。将CLR集成到SQL数据库,数据库开发者现在能完成单用Transact-SQL不可能或难以完成的任务。VisualBasic.NET和C#是现代编程语言,他们提供对数组、用户定义的例外处理、和集合的完全支持。开发者能充分发挥CLR的集成作用来编写具有更复杂的逻辑且更适合于使用如VisualBcsic.NET和C#的语言的计算任务的代码。除了CLR集成外,SQLSERVER还增加了对用户定义类型(UDT)的支持,这是使开发者能扩展数据库的标量类型系统的新机制。从应用的体系结构角度UDT提供两个关键好处它们在内部状态和外部行为之间提供强大的封装(在客户机机及服务器双方),且它们提供与其它有关服务器特征的深度集成,一旦定义了UDT,它能在可在SQLSERVER中使用的系统类型的所有上下文中使用,包括到定义、变量、参数、函数结果、光标、触发器和复制。在数据库服务器上定义UDT的过程如下完成a)在遵循用于UDT创建的规则的受管代码中创建一个类;b)使用CREATEASSAMBLY语句加载将包含到服务器上数据库的汇编码;c)使用CREATETYPE语句在数据库中创建展现受管代码UDT的类型。到此,能在表定义中使用UDT。当在受管码中创建UDT定义时,类型必须满足下列要求a)它必须标记成Serializable(可串行化);b)它必须用SqlUserDefinedTypeAttribute修饰;c)类型应是通过实现INullable接口得知的NULL;d)类型必须具有没有自变量的公共构造器;和e)类型应通过实现下列方法支持到字符串的双向转换1,PublicStringToStringU;和2.PubicShared<type>Parse(SqlStrings)。通过引用整体结合到这里的共同未定的、普通转让的,专利申序列请号为10/692,225,题为“SystemAndMethodForObjectPersistenceInADatabaseStore-在数据库存储中用于对象持续性(Persistence)的系统和方法”,它描述了UDT的另外的特征,其中对UDT的CLR类型定义的字段和行为用描述对数据库存储中UDT范例的布置结构的存储属性注释。具体来说,定义UDT的CLR类的每个字段用控制诸如大小、精度、比例等类型的存储方面的存储属性注释。在一实施例中,这是通过用名为SqlUdtField()的客户机存储属性注释每个字段达到的。此属性用附加的存储指示注释字段,当对象被串行化到盘时实施这些指示。此外,在CLR类中定义的每个受管的行为(如能在UDT对象上引用的如返回字段的值的方法)用标记对该受管行为的等价结构访问路径的属性注释。在一实施例中,用于此目的的客户机属性命名SqlUdtProperty(),而数据库服务器(如SQLSERVER)认为用此客户机属性标记的属性的实现将委托给作为属性定义的部分指定的字段。这使服务器在结构上优化对属性的访问而不必创建范例并引用在范例上的行为。图l是定义UDT的CLR类的示例代码表。如所示,CLR类如上所述地用SqlUdtField()和SqlUdtProperty()客户机属性注释。具体说来,SqlUdtField()客户机属性在行5、8、37和49处添加以注释示例的UDT类定义的对应字段。SqlUdtProperty()客户机属性在行11、24添加以注释该类的对应受管行为。然后,定义UDT的CLR类被编译成动态链接库(d11)。然后使用下面T-SQL脚本命令可创建包含编译的类的汇编码createassemblytestfrom‘c\test.dll’go然后能使用下列T-SQL脚本命令在服务器上创建UDTcreatetypebaseitemexternalname[test][baseitem]go一旦在服务器上创建了UDT,能如下创建一表(如“MyTable”)该表的属性定义成UDT类型createtablemytable(itembaseitemitemidasitemID)go新的项能如下地添加到该表declare@iBaseItemset@i=convert(baseitem’’)insertintomytablevalues(@i)go然后在查询中能使用UDT表达式.如SELECTitem.ID,Item.NameFROMMyTable。有了将CLR集成到SQLSERVER和从受管代码中的类定义确定UDT的能力,应用程序现在能例示由受管代码类定义的类型的对象,并使那些对象作为UDT保持在关系数据库存储中。此外,定义UDT的类还能包括在该类型的对象上实现具体行为的方法。然后应用程序能将定义成UDT类型的对象例示,并能在那些对象上引用受管的行为。当已定义成UDT的类的对象在CLR中例示时,该对象能通过对象串行化的处理保持在数据库存储中,其中该类的变量的值被传输到物理存储(如硬盘)之中。图2示出在存储器中一个对象被串行化到其在盘中保持的形式。该对象能以图3所示的格式的传统关系数据库表的形式保持在数据库存储中。如图示,该表包括指定的UDT的一列。保持的指定UDT的对象的串行化值占据UDT列的一格。再参考图2,当一应用程序生成包括引用保持在数据库存储的UDT对象的受管行为(如返回UDT对象的字段值的行为)的谓词或表达式的查询时,保持的对象必须被解串联化(有时称为“hydrating-水合”),而CLR必须对整个对象分配存储器以接收其存储的值。然后CLR必须调用返回查询的主题的值的UDT类的实际方法(即行为)。如在上述序列号为10/692,225的共同未定的专利所述,在UDT的CLR类定义中的SqlUdtField()和SqlUdtProperty()注释能由数据库服务器使用,以便也允许对指定的UDT字段的值的直接结构访问,而不需要对象的水合。一种得益于CLR集成及在SQLSERVER中提供UDT的新的技术是2003年8月21日提交序列号为10/646,646的共同未定的、普通转让的专利中描述的存储平台,该专利题为“StoragePlatformforOrganizing,Searching,AndSharingData(组织、搜索和共享数据的存储平台)”,通过引用整体结合到这里。图4是示出在此共同未定的专利中描述的存储平台的体系结构300的方框图。该存储平台有时称为“WinFs”。如图4所示,该存储平台300包括在数据库引擎314上实现的数据存储302。在一个实施例中,数据库引擎包括如微软SQLSERVER关系数据库引擎的关系数据库引擎。下面将更详细描述,数据存储302实现一数据模型304,它支持以项及项之间的关系的形式的数据的组织、搜索、共享、同步、和安全性。在如模式340的模式中描述特定项的类型,且如在在下面更详细描述,存储平台300提供用于调配那些模式及扩展这些模式的工具346。在该数据存储302中实现的改变跟踪机制306提供跟踪对数据存储改变的能力。数据存储302还提供安全性能力308和升级/降级能力310。数据存储302还提供一组应用程序界面312以将数据存储302的能力向利用该存储平台的其它存储平台组件及应用程序(如应用程序350a,350b,和350c)展现。存储平台还包括应用程序界面(API)322,它使如应用程序350a,350b,和350c的应用程序有访问该存储平台的能力并访问存储在数据库中的数据。应用程序可结合如DLEDBAPl324和微软的WINDOWSWin32API326的其它API来使用存储平台API322。存储平台300还可向应用程序提供各种服务328,包括使便于在用户和系统之间共享数据的同步服务330。例如,同步服务330启用与具有与数据存储302相同格式的其它数据存储340的互操作能力,并访问具有其它格式的数据存储342。存储平台300还提供让数据存储302与如WINDOWSNTFS文件系统318的现有文件系统互操作的文件系统能力。在至少某些实施例中,存储平台320还能为应用程序提供附加能力,使数据能起作用并启用与其它系统交互。这些能力能以附加服务的形式体现.如InfoAgent服务334和通知服务332,以及以其它实用程序336的形式。在至少某些实施例中,存储平台体现在计算机系统的硬件/软件接口系统中或形成其完整的部分。例如而非限止,本发明的存储平台可体现在操作系统、虚拟机管理程序(VMM)、公共语言运行系统(CLR)或其功能等价、或Java虚拟机(JVM)或其功能等价之中,或形成它们的完整的部分。通过其共同的存储基础和计划化的数据,该存储平台使消费者、知识工作者和企业能更作有效地应用开发。它提供了丰富和可扩展的编程表面区域,不仅使其数据模型中内含的能力可用,还包括和扩展现有文件系统及数据库访问方法。在下面描述和各个附图中,本发明的存储平台300可称作“WinFS”。然而,使用此名字来指该存储平台仅仅是为了描述方便,不试图以任何方式施加限止。WinFS平台的数据模型借助项、项扩展、和关系定义数据库存储单元。“项”是存储信息的基本单元。数据模型提供用于说明项和项扩展并用于建立项之间的关系的机制。项是使用如拷贝、删除、传送、打开等操作可以存储和检索的单元。项旨在表示实际的和容易理解的数据单元.如联系人、个人、服务、位置、文档(所有各种类型)等。项扩展是扩展现有项的定义的方法,而关系是项之间定义的链接。在WinFS中,定义不同的项类型来存储信息。例如,对联系人、个人、位置、文档等定义项类型。由定义给定项的属性和特征的模式来描述每个项类型。例如“位置”项可定义成具有如Eaddresses、MetropolilanRegion、Neighborhood、和PostalAddress属性。一旦对给定的项类型定义了模式,使用调配工具将该模式翻译成对该项类型的对应的CLR类定义,然后在数据存储中从CLR类定义(以上述方式)创建UDT,以便让WinFS项类型的范例能保持在数据存储中。使用WinFSAPI322,应用程序(如应用程序350a,350b,350c等)能创建由该数据存储支持的项类型的范例,以便从存储平台的数据存储中存储和检索信息。存储在数据存储中的项类型的每个范例具有与其关联的唯一标识符(如Item_ID);在一个实施例中每个项标识符是全球唯一标识符,即“guid”。因此,WinFS平台充分调动CLR集成和数据库存储的UDT能力,以提供用于存储信息的项的平台。有了在SQLSERVER中UDT的范例,WinFS项的范例以图3示出的方式最终存储在数据库存储的表中。然后应用程序能提交对WinFS平台查询,以从数据存储中搜索和检查满足搜索准则的项。图5示出如何针对数据存储执行查询,以检索称为“Person”的项类型的范例。在步骤(1),应用程序使用WinFSAPI322的“FindAll”方法起动对满足特定搜索准则的所有项的查询—在此情况,Person类型的所有范例,其中在该类型的“Birthday”字段中的值大于一特定日期(如1999年12月31日)。在步骤(2)WinFSAPI322将“FindAll”操作翻译成SQL查询并将其提交给如SQLSERVER的底层数据库引擎。在步骤(3)数据库引擎针对PersonUDT的对应范例执行查询,并对PersonUDT的每个匹配范例返回存储的值。在此例中,在步骤(4)ADO.Net将从数据库存储返回的位转成CLR对象(即上面讨论的对象水合的过程)并将它们返回到WinFSAPI322。ADO.Net是Microsoft。NET架构的组件,它通过CLR将受管的代码访问提供给如SQLSERVER的数据源。然后WinFSAPI包装PersonUDT对象,并将它们作为Person类型的项返回给应用程序。UDT的每个范例可包括若干成员,它们代表如数字图象、视频、声频等的大对象。那些大对象通常存储在如BLOB、CLOB和NCLOB的数据类型范例中,或更具体地存储在Varbinary(max)、varchar(max)、nvarchar(max)之中。从数据库检索大型成员常常需要大量的时间和相当的带宽。此外,大多数UDT检索使用情况不需要对大的嵌入的成员的访问。因此,在业内对用于延迟取出UDT的指定成员的系统和方法存在需要。希望那样的系统和方法使初始取出UDT但没有指定成员,而指定成员以后在一旦请求时再取出。本发明满足这些与其它需要。
发明内容本发明针对用于延迟取出用户定义类型(UDT)的指定成员的系统和方法。指定的成员可以是大对象.如数字图象、视频、音频等。按照本发明,在从数据库服务器初始取出UDT后,将返回UDT的串行化版本,其中去除指定的成员,从而保护了有用的带宽并减少了完成该初始取出所需的时间量。一旦请求时,指定的成员能在以后从数据库服务器再取出,并返回而没有在初始取出期间提供的其它UDT成员。按本发明的一方面,可以通过产生标识到底层数据库中的UDT的路径的UDT容器的引用而执行初始取出。可从数据库检索UDT的串行化表示,并从串行化表示中去除指定的成员。然后该容器引用可被加在串行化表示之前,且该串行化表示可返回给客户机应用程序。按本发明的另一方面,该客户机应用程序可接收和解串行化该串行化表示。作为解串行化过程的一部分,对每个指定成员可构建一类型范例,它包括对应于指定的成员在数据库中位置的上下文信息。该上下文信息可包括对整个UDT的容器引用和对应的指定成员的单独的成员路径。然后每个指定的成员可通过将其上下文信息提供给数据库服务器而在以后时间再取出。按本发明的另一方面,在再取入期间指定的成员就象在初始取入时间那样返回。为启用此特征,标识在初始取入时间的UDT的版本的更新序列标记(USM)也能与该串行化表示一起返回给客户机应用程序。在再取入期间,USM可与上下文信息一起返回给数据库服务器。可使用USM来标识和检索指定成员在初始取入时的以前版本。按本发明的另一方面,在初始取入以后,整个UDT或各个指定的成员可返回给数据库服务器。若返回整个UDT,则向数据库服务器提供上下文信息以替代指定的成员。一旦返回给数据库服务器之后,就使用上下文信息来标识和替代指定的成员。若只返回各个指定的成员,则上下文信息与表示指定的成员的元数据注释等一起返回。本发明的其它特征和优点将从参考附图进行的例示实施例的下面详述中明白。在参考附图阅读下面详述后将更好地理解例示的实施例,附图是图1是示出对用户定义类型的受管代码类定义的示例代码段;图2是示出已在受管代码中例示的类型的范例的串行化及解串行化的方框图;图3是示出已保持-UserDefinedType的对象的数据库表的概图;图4是示出得益于本发明的特征的示例存储平台的方框图;图5是示出在图4示出的存储平台的上下文中执行针对用户定义类型的保持的对象的查询的过程的概图;图6是示出用于按本发明延迟取出用户定义类型的成员的示例系统的方框图;图7是用于按本发明延迟取出用户定义类型的成员的示例方法的流程图;图8是用于按本发明执行用户定义类型的初始取入的示例方法的流程图;图9是表示在其中实施本发明的具有各种计算设备的示例网络环境的方框图;图10是表示在其中实施本发明的示例计算设备的的方框图。具体实施例的详细说明以满足法定要求的特征来描述本发明的主题。然而描述本身不试图限止本专利的范围。相反,本发明者也认为,要求专利保护的主题也能以其它方式体现,以结合其它当前或未来的技术包括类似于本文档中描述的不同动作或元素。如上所述,本发明针对用于延迟取出用户定义类型(UDT)的指定成员的系统和方法。一般而言,本发明使UDT的特定成员,尤其是代表大对象的成员能指定为可延迟的成员。在初始取出UDT期间它可从数据库返回而不带可延迟的成员,从而保护了有价值的带宽并减少了完成取出所需的时间量。在请求后,在以后时间再取出被选择的可延时的成员而不返回在初始取出期间已提供的其它成员。可以理解,延迟检索的过程可称为惰性实现(lazymaterialization)过程,然而用于以下面描述的系统和方法的特定术语不旨在限止本发明的范围。在图6中示出用于按本发明延迟取出UDT的指定成员的示例系统。一般而言,数据库服务器600包括一底层数据存储610,它以如数据表612的关系形式存储数据。表612包括带若干行的UDT列614,每行包括UDT的一个范例。虽然不是必须,每个UDT范例可包括若干个大对象618a-c。表612还包括主键列616,它按如全球统一标识符(GUID)的唯一的标识符组织UDT范例。应该理解,表612还包括其它UDT列和其它关系列(未示出)。客户机650使用户能生成查询并将其提交给数据库服务器600,这种查询可请求从数据存储610取出特定的UDT范例。数据库服务器600还可包括公共语言运行系统(CLR)620,它使UDT范例能按CLR类定义来定义。下面示出对UDT的示例的类定义Person{StringFirstName;StringLastName;BlobPhoto;Collection<Address>Addresses;}Address{StringZip;BlobMap;}如上所述,按本发明的一个方面可将UDT的特定成员指定为可延迟的成员。若查询在以后提交给请求取出UDT的数据库服务器600,则在请求之后可延迟的成员作为查询执行的部分从UDT去除。然后可延迟成员可在以后的请求之后再取出。可延迟成员可通过注释它们(如使用由CLR20识别的客户机属性)而被指定。例如,可延迟成员可使用“IsDelayable”属性注释。带有示例的被注释的可延迟成员的UDT如下所示Person{StringFirstName;StringLastName;[SqlUdtField(IsDelayable=true;)]SqlBytesPhoto;MultiSet<Address>Addresses;}Address{StringZip;[SqlUdtField(IsDelayable=true;)]SqlBytesMap;}一旦定义了UDT并注释了可延迟成员,查询用数据存储610注册。数据存储610读出UDT的属性并基于该注释标识可延迟的UDT成员。在数据存储610处注册UDT后.如下所述,可用延迟取出对注释的可延迟成员检索该UDT。在图7示出用于按本发明延迟取出UDT的指定成员的示例方法的流程图。在动作710,请求取出UDT的初始取出请求被提交给数据库服务器600。如上所述,为提供如保存带宽和减少完成取出操作所需的时间的优点,按本发明的取出查询可请求延迟取出指定的可延迟的UDT成员。较佳地,取出查询按默认不延迟取出可延迟的成员。相反,取出查询最好必须包括专门请求来调用延迟取出。因此,为启用延迟取出,SELECT语句的结果表可扩展到主持延迟取出的子句。例如,那样延迟取出子句可以是WITH[REFERENCE]LOCATOR子句。包括WITH[REFERENCE]LOCATOR子句的示例的设计清单如下所示<column_specifier>∷={column_name|<Delayable-value>[WITH([REFERENCE]LOCATOR)]|expression|IDENTITYCOL|ROWGUIDCOL}<Delayable-value>∷={delayable_column_name|<Delayable-value>.<UDT-valued-udt-member>|TREAT(<Delayable-value>AS<type>)}<UDT-valued-udt-member>∷={<public-udt-valued-field>|<public-udt-valued-sql-property>}上面示出的语法增强启用对任何UDT范例的延迟取出。例如那样的UDT范例可以是顶层UDT、在某个其它UDT中的嵌入的UDT-值的成员、已投射到其子类型或超类型之一的UDT、或任何前三种类型的组合。下面示出请求延迟取出的示例取出查询SELECTperson_colWITH(LOCATOR)FROMperson_tableWHEREpersoncol.LastName=′Jones′;有两种可实现延迟取出的方式引用语义和值语义。在引用语义方法中,再取出操作作为在再取出操作本身的时间的成员检索延迟的成员。因此,在初始取出后对延迟的成员作的任何改变与再取出一起被传播和检索。在值语义方法中,再取出操作作为执行的初始取出时间的成员检索可延迟的成员。因此,值语义提供延迟的和非延迟成员之间读的一致性。在下面整篇描述中讨论引用语义和值语义的实现。在动作712,在数据库服务器600处执行取出查询。图8示出按本发明执行取出查询的示例方法。在图8中示出的动作810-820是动作712中的子动作。在动作810,数据库服务器600验证请求的UDT是唯一可识别的。验证包括建立请求的UDT存储在对其可生成访问路径的表或视图中。那样的访问路径使得在以后能再取出完全相同的请求的逻辑UDT。验证能包括确保在访问路径中的所有表包括主关键词或唯一的索引.如关键词列616。若该UDT不是唯一可标识的,则返回—错误消息。在动作812,数据库服务器600生成UDT容器引用。UDT容器引用包括上面讨论的UDT访问路径,并最终编码数据库、模式、表/视图、关键词列或对UDT路径的关键词列值的所有逻辑名字。在容器引用中的所有信息相对于可由客户机650访问的对象是“逻辑的”。因此,只要容器引用出现,结合可由客户机650请求的动作和操作,容器引用的语义对客户机650是可理解的。容器引用不受数据库服务器600的实现细节的限止。可对数据库服务器600添加附加的语法来编码容器引用。在动作814,数据库服务器600确保UDT容器引用不会用不适当的或未授权的信息披露而损害安全性。动作814是可选的。例如,安全性可通过验证提交查询的用户已访问包括在访问路径的关键词列部分的所有列和值来达到。另外,安全性可通过加密值并以加密形式返回它们来达到。在动作816,从数据存储610检索UDT范例的串行化表示。在动作818,从被检索的UDT去除UDT的可延迟成员。具体说来,当每个UDT范例返回给客户机650时,对被返回的特定类型加载元数据,且枚举可延迟的成员并将其从串行化表示中逻辑上去除。在动作820中,用UDT容器引用给检索的UDT加前缀。因此,该范例带着UDT容器引用和标记成IsDelayable=true的UDT略去成员的串行化形式返回给客户机650。对于值语义,数据库服务器600完成某些附加动作作为取出查询的执行的一部分。具体说来,数据库服务器600确保包含取出查询的语句在用户事务的上下文中执行。此外,服务器600生成和返回作为UDT范例的一部分的UpdateSequenceMaker(USM),它是用于提供关于再取出操作的读一致性的版本化时间标记。回到图7,在动作714,带着去除的可延迟的成员和加前缀的容器引用的UDT被返回给客户机650。在动作716,返回的UDT被解串行化。作为解串行化过程的一部分,在客户机650处的受管的解串行化器标识被略去的、可延时的UDT成员,并对每个那样延迟的成员构造对应的CLR类型.如SqlBytes和SqlChars。对每个延迟成员构造的CLR类型包括对整个UDT以及对单独的延迟成员的单独的成员路径的加前缀的UDT容器引用。因此,对每个成员的CLR类型范例是提供到数据库服务器600中的该单独成员的路径的cookie程序。该cookie程序是明确标识在数据库600上延迟成员的单独范例但不指向客户机650的字节的序列。在客户机650处的程序通常不作出对cookie程序的改变,并以对数据库服务器600再取出请求的初始形式使用该cookie程序。设置包括单独的成员路径的每个延迟的成员的全部上下文在客户机650处进行,以达到更好的性能和可伸缩性。客户机的解串行化器在所有返回的UDT范例上作完整类型的遍历而不管这些范例是否包括延迟的成员。因此,与在数据库600处设置全上下文不同,在客户机650处设置完整上下文不需要附加的遍历返回的UDT。此外,在客户机650处设置完整上下文从数据库服务器600卸载了额外的工作,导致可伸缩性的增多。按本发明的CLR类型可被增强以支持由cookie程序状态作背景的情况。此外,那些类型可增强,以便在未完全具体化时,如果试图使用对应范例的将返回一例外信息。重要的是,还能增强CLR类型以提供“Fill”方法,它自动地从数据库服务器600再取出对于对应范例的完整表示。Fill方法将取到数据库服务器600的连结作为自变量。与使用Fill方法不同,对服务器连结的引用可在解串行化期间隐含地存储在客户机650处。在动作718,客户机650提交再取出选定的延迟成员的请求。再取出操作使被选择的延迟成员能被检索而不检索在初始取出期间返回的非延迟的成员。实现再取出操作,使得最小化将由用户完成的任务的量和复杂性。通过在对应的CLR类型的范例上的Fill方法实现再取出。这些方法引用新添加的远程过程调用(RPC)进入点,它采取cookie程序并返回对应的单个延迟的成员。具体说来,为了再取出特定成员,用户只需对相应的范例调用Fill方法,并指定到数据库服务器600的连结。对于值语义,还提供初始取出的USM。在引用Fill方法之后,在数据库服务器600上执行存储的过程,它接收UDT容器引用、对应的单独成员路径、和(若可应用的话)USM。在动作720,在数据库服务器600处执行再取入操作。为执行再取出,数据库服务区进入点使用延迟取出语法分析UDT容器引用,并构建能执行检索整个UDT的查询树。一旦获得整个UDT,使用单独的成员路径信息来向下遍历需要返回的被选择的单独成员。此操作可包括在范例的子类型和超类型之间的铸造。对于值语义,使用提供的USM来标识和检索从初始取出时间以来的请求成员的以前版本。在动作722,在定位了请求的成员之后,它被返回给客户机650。在动作724,由客户机650接收返回的成员。CLR类型的范例读出成员表示,设置成员表示到后备表示,并设置范例的内部状态到“已填满”。因此.如上述参考图7和图8列出,本发明启用延迟检索UDT的指定成员。除了提供从数据库服务器600用于取出UDT成员的方法以外,本发明还能用于提交带延迟的成员的“进入的(inbound)”UDT到服务器600。在客户机650作出对UDT成员的改变并返回UDT或单独改变的成员到数据库服务器以便在数据存储610中存储时,本发明的此特征特别有用。在此情况,客户机650可提交UDT或单独改变的成员到数据库服务器650而不必首先检索UDT的可延迟的成员。作为输入参数,客户机650可向数据库服务器600返回包含未填充的成员的整个UDT范例或CLR类型的未填充的范例。在返回带未填充的成员的整个UDT的情况,在客户机650处受管的串行化器发送包括UDT引用615和对应的单独成员路径的全cookie程序以代替每个未填充的成员值。在输入上,数据库服务器600为嵌入的延迟成员校验UDT,并扩展和替代任何找到的延迟成员。在输入的界限内完成未填充的成员的扩展以保证正确的语义。可从其它范例或从同一范例的其它版本指定诸成员。在CLR类型的独立范例的情况,客户机驱动程序发送cookie程序表示和表明范例身份的元数据注释。元数据注释使得有可能区分cookie程序和带匹配序列的实际二进制/字符值。从上述可明白,本发明的各种系统、方法、和方面的所有或部分可体现在硬件、软件、或两者的组合中。当体现在软件中时,本发明的方法和装置,或其特定方面及部分能以程序代码(即指令)的形式体现。此程序代码可存储在如磁、电、或光存储介质的存储介质中,包括但不限于,软盘、CD-ROM、CD-RW、DVD-ROM、DVD-RAM、磁带、闪存、硬盘驱动器或其他机器可读存储介质,其中当该程序代码加载到机器(如计算机或服务器)并由其执行时,该机器变成用于实施本发明的装置。在其上执行程序代码的计算机通常包括处理器、由处理器可读的存储介质(包括易失和非易失存储器和/或存储单元)、至少一个输入设备和至少一个输出设备。程序代码能以高级过程语言或面向对象的编程语义实现。另外,程序代码能以汇编或机器语言实现。在任何情况,语言能是编译的或解释的语言。本发明也能以通过某种传输介质传输的程序代码的形式体现,传输介质如通过电线或电缆、通过光、经过包括局域网、广域网、因特网或内联网的网络或通过任何另外传输形式,其中当该程序代码加载到一机器(如计算机)并由其接收和执行时,该机器成为实施本发明的装置。当在通用处理器上实现时,程序代码可与处理器组合以提供类似于专用逻辑电路操作的单独的装置。此外,本发明能结合可配置成计算机网络一部分或在分布式计算环境中的任何计算机或其它客户机机或服务器上实施。在这方面,本发明适合于任何计算机系统或环境,它们具有任何数量的存储器或存储单元、在任何数量存储单元或卷中发生的任何数目的应用程序和进程,那些卷能结合按本发明用于保持在数据库存储中的对象的过程使用。本发明还能应用于具有服务器计算机和客户机计算机的环境中,它们配置在具有远程或本地存储的网络环境或分布式计算环境中。本发明也能应用于独立的计算设备中,它们具有编程语言功能、用于结合远程和本地服务生成接收和发送信息的解释和执行能力。分布式计算通过诸计算设备和系统之间的交换以便于共享计算机资源和服务。这些资源和服务包括但不限于信息交换、高速缓存存储、和对文件的磁盘存储。分布式计算得益于网络连结,允许客户机机充分调用它们的协同能力有利于整个企业。在这方面,各种设备可具有应用程序、对象或资源,它们可涉及结合本发明的对象保持方法完成的处理。图9提供示例连网的或分布的计算环境的原理图。分布式计算环境包括计算对象10a、10b等,和计算对象或设备110a、110b、110c等。这些对象可包括程序、方法、数据存储、可编程逻辑等。对象可包括如PDA、电视、MP3播放器、个人电脑等的相同或不同设备的部分。每个对象可通过通信网络14与另外对象通信。此网络本身可包括向图9的系统提供服务的其它计算对象和计算设备,并且本身可代表多个互连网络。按本发明的一方面,每个对象10a、10b等或110a、110b、110c等可包括应用程序,它可使用API或其它对象、软件、固件、和/或硬件,以请求使用那些用于实现本发明的对象保持方法的过程。可以理解.如110c的一个对象可包容在任何其它计算设备10a、10b等或110a、110b等之中。因此虽然画出的物理环境可示出计算机的连结设备,那样的例示仅是例子,物理环境可另外画出或描述成包括如PDA、电视、MP3播放器等各种数字设备。以及如接口、COM对象等的软件对象。有各种支持分布式计算环境的系统、组件、和网络配置。例如,计算系统可通过有线或无线系统,通过本地网络或广泛分布的网络互相连结。当今,许多网络连结到因特网,它提供广泛的分布式计算的基础结构并环绕许多不同的网络。任何基础结构能用于伴随本发明作出的示例性通信。因特网通常指利用计算机网络专业中众知的TCP/IP协议套件的网络和网关的集合。TCP/IP是“传输控制协议/网间协议”的缩写。因特网可描述成由计算机互连的地理上分布的远程计算机网络的系统,那些计算机执行允许用户通过网络互连和共享信息的网络协议。由于这种广泛分布的信息共享.如因特网的远程网络至今已发展成开放系统,开发者能对它设计软件应用程序,以便基本上无限止地完成专门的操作和服务。因此,网络体系结构启用许多网络拓扑.如客户机/服务器、对等、或混合体系结构。“客户机”是使用与它无关的其它类或组的服务的类或组的成员。因此,在计算中客户机是一过程,即大致说是请求由其它程序提供服务的一组指令或任务。客户机过程利用请求的服务而不必“知道”关于其它程序或服务本身的任何工作细节。在客户机/服务器体系结构中,尤其网络系统中,客户机通常是访问由如服务器的其它计算机提供的共享网络资源的计算机。在图9的例子中,110a、110b等计算机可看作客户机机,而如10a、10b等计算机可看作服务器,虽然根据情况任何计算机可看作客户机机、服务器、或两者。任何这些计算设备能以涉及本发明的对象保持技术的方式处理数据。服务器通常是通过如因特网的远程或本地网络可访问的远程计算机系统。客户机过程可以是在第一计算机系统中活动的,而服务器过程可以是在第二计算机系统中活动的,它们通过通信介质互相通信,从而提供分布式功能并允许多个客户机得益于服务器的信息聚集能力。任何被利用来遵循本发明的保持机制的软件对象可分布在多个计算设备中。客户机机和服务器可利用由协议层提供的功能互相通信。例如超文本传输协议(HTTP)是结合WorldWideWeb(WWW-万维网),或“Web”使用的常用协议。通常,计算机网址。如网际协议(IP)地址或如统一资源定位器(ULR)的其它引用能用于互相标识服务器或客户机机。网址能称为URL地址。经过任何可用的通信介质可提供通信。因此,图9示出示例的连网或分布式环境,它具有通过网络/总线与可采用本发明的客户机计算机通信的服务器。按本发明,网络/总线14可以是LAN、WAN、内联网、因特网、或某种其它网络介质,它们具有若干客户机机或远程计算设备110a、110b、110c、110d、110e等.如便携计算机、手持计算机、瘦客户机、连网装置、或如VCR、TV、电炉、灯光、加热器等其它设备。因此可认为,本发明可应用于连接这些设备希望能维持保持的对象的任何计算设备。在通信网络/总线14是如因特网的网络环境中,服务器10a、10b等能是客户机机110a、110b、110c、110d、110e等通过若干如HTTP的已知协议的一个与其通信的服务器。服务器10a、10b等也能用作客户机机110a、110b、110c、110d、110e等,这是分布式计算环境的特征。通信可以因地制宜地是有线或无线的。客户机设备110a、110b、110c、110d、110e等可以或可以不通过通信网络/总线14通信,并可具有与其关联的独立通信。例如在TV或VCD的情况下,可以是或可以不是连网地控制,每个客户机计算机110a、110b、110c、110d、110e等和服务器计算机10a、10b等可装备各种应用程序模块或对象135,并具有到各种类型的存储单元或对象的连接和访问,通过它们文件或数据流能被存储,或文件或数据流的各部分能被下载、传输或迁移到那里。任何计算机10a、10b。110a、110b等可负责维护、更新用于存储按本发明处理的存储数据的数据库、存储器、或其它存储单元20。因此,本发明能用于计算机网络环境,它具有能访问计算机网络/总线14并与其交互的客户机计算机110a、110b等,以及可与客户机计算机110a、110b等其它设备交互的服务器,和数据库20。图10及以下描述旨在提供本发明可实施的被连接的合适的计算设备的简要描述。例如,在图9中示出的任何客户机机和服务器计算机或设备可采取此形式。然而可以理解,所有类型的手持、便携或其它计算设备和计算对象都可被预期结合本发明而使用,也就是一个计算环境中从任何地方数据可被生成、处理、接收/或传输。接收和/或发送数据的任何设备考虑可结合本发明使用。虽然以下描述的是通用计算机,但这仅是一例,本发明可用具有网络/总线可互操作性和交互的瘦客户机上实现。因此,本发明可在连网的接纳服务的环境中实现,其中只涉及少量或最少的客户机资源。例如,一个连网的环境,其中客户机设备仅作为到网络/总线的接口。如放在装置中的对象。实质上,用于本发明的对象保持方法的操作所期望的或合适的环境是可存储数据或从中检索数据并将其发送到另外计算机的任何地方。虽然不是要求的,本发明能通过由对设备或对象的服务的开发者使用的操作系统实现,和/或包括在按本发明操作的应用程序或服务器软件之中实现。软件能以如由客户机工作站、服务器或其它设备的一个或多个计算机执行的程序模块那样的计算机可执行指令的一般上下文描述。一般而言,程序模块包括例程、程序、对象、组件、数据结构等,他们完成特定任务或实现特定的抽象数据类型。典型地,在各种实施例中,程序模块的功能能按需要组合或分布。此外,本发明能用其它计算机系统配置和协议实施。适用于本发明的其它众所周知的计算系统及环境包括但不限于个人计算机(PC)、自动取款机、服务器计算机、手持或膝上设备、多处理器系统、基于微处理器的系统、可编程消费电子设备、网络PC、电器装置、灯、环境控制单元、小型机、大型计算机等。图10示出其中可实现本发明的合适的计算系统环境的例子100,虽然如上阐明,计算系统环境100仅是合适计算环境的一例,并不试图对本发明的使用或功能的范围提出任何限止。计算环境100也不解释为对示例的操作环境100中示出的任何组件或其组合具有任何依赖性或需求。参考图10,用于实现本发明的示例系统包括计算机110格式的通用计算设备。计算机110的组件可包括但不限于处理单元120,系统存储器130和将包括系统存储器的各种系统组件连接到处理单元120的系统总线121。系统总线121可以是若干类型总线结构的任一种,包括存储器总线或存储控制器、外围总线、和使用各种总线体系结构的任一种的局部总线。作为例子而非限止,那些体系结构包括工业标准体系结构(ISA)总线、微通道体系结构(MCA)总线、增强的ISA(EISA)总线、视频电子标准协会(VESA)局部总线、和外围部件互连(PCI)总线(也称Mezzanine总线)。计算机110通常包括各种计算机可读介质。计算机可读介质能是可由计算机110访问的任何有效的介质,并包括易失和非易失、可移动和不可移动介质。作为例子而非限止,计算机可读介质可包括计算机存储介质通信介质。计算机存储介质包含以任何方法或技术实现的易失和非易失、可移动和不可移动介质,用于存储如计算机可读指令、数据结构、程序模块或其它数据等信息。计算机存储介质包括但不限于RAM、ROM、EEPROM、闪存或其它存储技术、CDROM、数字多功能盘(DVD)或其它光盘存储器、盒式磁带、磁带、磁盘存储或其它磁存储设备,或任何其它能用于存储所希望的信息并能由计算机110访问的介质。通信介质通常体现为诸如载波或其它传输机制的调制数据信号中的计算机可读指令、数据结构、程序模块或其它数据中,并包括任何信息发布介质。术语“调制数据信号”意指一种信号,它具有其一个或多个特征以在信号中作为编码信息的方式设置或被改变。作为例子而非限止,通信介质包括有线介质如有线网络或直线连结的有线介质、和诸如声版的、RF、红外或其它无线介质的无线介质。任何上述的组合也应包括在计算机可读介质的范围内。系统存储器130包括易失和/或非易失存储器形式的计算机存储介质.如只读存储器(ROM)131和随机存储器(RAM)132。包括如在起动期间帮助在计算机110中的元件之间传输信息的基本例程的基本输入/输出系统133(BIOS)通常存储在ROM131中。RAM132通常包含数据和/或程序模块,它们立即可访问到和/或表现为由处理单元120进行操作。作为例子而非限止,图10示出操作系统134、应用程序135、其它程序模块136和程序数据137。计算机110也可包括其它可移动/不可移动、易失/非易失计算机存储介质。只作为例子,图8(应是图10,原文错误)示出读写不可移动、非易失磁介质的硬盘驱动器141、读写可移动、非易失磁盘152的磁盘驱动器151、读写如CD-RW、DVD-RW或其它光介质的可移动、非易失光盘156的光盘驱动器155。可用于示例的操作环境的其它可移动/不可移动、易失/非易失,计算机存储介质包括但不限于磁带盒、闪存卡、数字多功能盘、数字视频带、固态RAM、固态ROM等。硬盘驱动器141通常通过如接口140的不可移动存储器接口连接系统总线121,而磁盘驱动器151和光盘驱动器155通常由如接口150的可移动存储器接口连接到系统总线121。上面讨论及图10中示出的驱动器及其相关计算机存储介质为计算机110提供计算机可读指令、数据结构、程序模块及其它数据的存储。例如,在图10中硬盘驱动器141用作存储操作系统144、应用程序145、其它程序模块147和程序数据147。注意,这些组件可与操作系统134、应用程序135、其它程序模块136和程序数据137相同或不同。操作系统144、应用程序145、其它程序模块146和程序数据147在这里被赋予不同序号,以表示至少它们是不同的副本。用户可通过如键盘162和诸如鼠标、跟踪球或接触垫那样的定位设备161等输入设备将命令和信息输入到计算机110,其它输入设备(未示出)可包括话筒、操纵杆、游戏垫、圆盘卫星天线、扫描仪等。这些和其它输入设备常通过连结到系统总线121的用户输入接口160连接到处理单元120,但也可通过其它接口和总线结构连结,诸如并行口、游戏口或通用串口总线(USB)。图形接口182也可被连接到系统总线121。一个或多个图形处理单元(GPU)184可与图形接口182通信。监视器191或其它类型显示设备也通过与视频存储器186通信的诸如视频接口190的接口连接到系统总线121。除监视器191以外,计算机还包括如扬声器197和打印机196等其它外围输出设备,它们可通过输出外围接口195连接。计算机110可使用到如远程计算机180的一个或多个远程计算机的逻辑连接在连网的或分布式环境中操作。远程计算机180可以是个人计算机、服务器、路由器、网络PC、对等设备或其它公共网络节点,并通常包括上面对于计算机110描述的许多或所有元件,虽然图10中只示出存储器设备181。图10中画出的逻辑连结包括局域网(LAN)171和广域网(WAN)173,但也可包括其它网络/总线。那样的网络环境在家庭、办公室、企业范围的计算机网络、内联网和因特网中是常见的。当在LAN连网环境中使用时,计算机110通过网络接口或适配器170连接到LAN171。当在WAN连网环境中使用时,计算机110通常包括调制解调器172或用于通过如因特网的WAN173建立通信的其它装置。能是内置或外接的调制解调器172可通过用户输入接口160或其它合适的机制连接到系统总线121。在连网环境中,对于计算机110画出的程序模块或其部分可存储在远程存储器设备中。作为例子而非限止,图10示出驻留在存储器总设备181上的远程应用程序185。可以理解,示出的网络连结是示例的,并可使用在计算机之间建立通信链路的其它装置。如前所述,本发明针对延迟取出UDT的指定成员。本发明尤其有利于延迟取出如数字照片、视频等大对象。可以理解,对上述实施例可作出改变而不偏离其中的广泛的发明概念。例如,虽然上面的本发明的实施例被描述成在微软的SQL数据库管理系统中实现,可以理解,本发明可体现在支持创建用户定义类型的任何数据库管理系统中。此外,虽然本发明的某些方面被描述成体现上述的WinFS存储平台的上下文中,可以理解,本发明的那些方面不意味着限剩于在那个环境中实现。相反,本发明的方法和系统能够体现在被要求能存储和检索用户定义类型的成员的任何系统中。因而可以理解,本发明不限于所揭示的特定实施例,而试图在由附后的权利要求中定义的本发明的精神和范围中复盖所有的修改。权利要求1.一种用于延迟取出用户定义类型的指定成员的方法,其特征在于,所述方法包括生成对所述用户定义类型的容器引用,它标识到数据存储中所述用户定义类型的路径;从所述数据存储中检索所述用户定义类型的串行化表示;从所述串行化表示中去除所述指定成员;以及将所述容器引用附加到所述串行表示中。2.如权利要求1所述的方法,其特征在于,还包括按注释所述指定成员的对应类定义在所述数据存储中注册用户定义类型。3.如权利要求1所述的方法,其特征在于,还包括接收请求带有所述指定成员的延迟取出的所述用户定义类型的初始取出的查询。4.如权利要求1所述的方法,其特征在于,还包括向客户机应用程序返回所述串行化表示和所述附加的容器引用。5.如权利要求1所述的方法,其特征在于,还包括在生成所述容器引用之前验证,所述用户定义类型是唯一可标识的。6.如权利要求1所述的方法,其特征在于,还包括在将所述容器引用附加到所述串行化表示之前确保它的安全性。7.如权利要求1所述的方法,其特征在于,还包括将当前更新序列标记附加到所述串行化表示。8.如权利要求1所述的方法,其特征在于还包括接收再取出所述指定成员的请求,所述请求包含上下文信息,它包括所述容器引用和到所述指定成员的单独的成员路径;基于所述上下文信息从所述数据存储中检索所述指定的成员;以及返回所述指定的成员。9.如权利要求8所述的方法,其特征在于,包括接收再取出所述指定的成员的请求,所述请求还包括对应于所述用户定义类型的初始取出的更新序列标记。10.如权利要求9所述的方法,其特征在于,包括从所述数据存储中检索所述指定成员的先前版本,所述先前版本由所述更新序列标记标识。11.如权利要求1所述的方法,其特征在于,还包括接收所述用户定义类型的再串行化表示,其中所述指定的成员由包括所述容器引用及到所述指定成员的单独的成员路径的上下文信息替代;用所述指定成员替代所述上下文信息,所述指定成员基于所述上下文信息标识;以及在所述数据存储处存储所述再串行化表示。12.如权利要求1所述的方法,其特征在于,还包括接收包括所述容器引用和到所述指定成员的单独的成员路径的上下文信息,并接收将所述上下文信息标识成到所述数据存储中所述指定成员的位置的路径的元数据注释;用所述指定成员替代所述上下文信息,所述指定成员基于所述上下文信息标识;以及在所述数据存储处存储所述指定成员。13.一种具有用于执行权利要求1的所述步骤的计算机可执行指令的计算机可读介质。14.一种用于延迟取出用户定义类型的指定成员的方法,其中所述延迟取出在初始取出之后请求,所述初始取出返回用户定义类型的串行化表示而没有所述指定成员,所述串行化表示具有附加到所述用户定义类型的容器引用,所述容器引用标识到所述数据存储中所述用户定义类型的路径,所述方法包括通过构造对应于所述指定成员类型范例解串行化所述串行化表示,所述类型范例包括上下文信息,它包括容器引用和到所述用户定义类型中所述指定成员的单独成员路径;以及提交对所述指定成员的再取出请求到数据库服务器,所述再取出请求包括所述上下文信息。15.如权利要求14所述的方法,其特征在于,还包括提交所述初始取出查询到所述数据存储,所述查询请求所述指定成员的延迟取出。16.如权利要求14所述的方法,其特征在于,还包括接收带有对应于所述初始取出的附加的更新序列标记的所述用户定义类型的所述串行化表示。17.如权利要求16所述的方法,其特征在于,包括提交所述再取出请求到所述数据服务器,所述再取出请求还包括所述更新序列标记。18.如权利要求14所述的方法,其特征在于,还包括响应于所述再取出请求,接收所述指定成员。19.如权利要求18所述的方法,其特征在于,包括接收由对应于所述初始取出的一个更新序列的标记标识的所述指定成员的以前版本。20.如权利要求14所述的方法,其特征在于,还包括再串行化所述用户定义类型的所述表示,从而用所述上下文信息替代所述指定成员;以及提交所述再串行化表示给数据库服务器,用于在所述数据存储中存储。21.如权利要求14所述的方法,其特征在于,还包括向所述数据库服务器提交所述上下文信息,以及将所述上下文信息标识成到所述数据存储中所述指定成员的位置的路径的元数据注释。22.一种具有用于完成权利要求1所述的步骤的计算机可执行指令的计算机可读介质。23.一种用于延迟取出用户定义类型的指定成员的系统,其特征在于,所述系统包括一个数据库服务器、一个数据存储和一个客户机应用程序;其中,所述客户机应用程序提交请求所述用户定义类型的初始取出的查询,所述查询请求所述指定成员的延迟取出;以及其中,所述数据库服务器返回包括其中去除指定的成员的所述用户定义类型的串行化表示的初始取出结果,所述初始取出结果还包括标识到所述数据存储中所述用户定义类型的路径的附加的容器引用。24.如权利要求23所述的系统,其特征在于,根据其中所述指定成员被注释成可延迟成员的对应的类定义来定义用户定义类型。25.如权利要求23所述的系统,其特征在于,所述初始取出结果还包括对应于所述初始取出的附加的更新序列标记。26.如权利要求23所述的系统,其特征在于,所述客户机应用程序向所述数据库服务器提交再取出请求,所述再取出请求包括上下文信息,后者包括所述容器引用和到所述指定成员的单独的成员路径。27.如权利要求26所述的系统,其特征在于,所述数据库服务器基于所述上下文信息从所述数据存储检索所述指定成员,并将所述指定成员返回给所述客户机应用程序。28.如权利要求26所述的系统,其特征在于,所述再取出请求还包括对应于所述初始取出的更新序列标记。29.如权利要求28所述的系统,其特征在于,返回给所述客户机应用程序的所述指定的成员包括基于所述更新序列标记标识的所述指定成员的先前版本。30.如权利要求23所述的系统,其特征在于,所述客户机应用程序将所述用户定义类型的再串行化表示提交给所述数据库服务器,所述再串行化表示包括由包含所述容器引用和所述指定成员的单独成员路径的上下文信息替代的所述指定成员。31.如权利要求30所述的系统,其特征在于,所述数据库服务器用所述指定的成员替代所述上下文信息,所述指定成员基于所述上下文信息标识。32.如权利要求31所述的系统,其特征在于,所述再串行化表示被存储在所述数据存储中。33.如权利要求23所述的系统,其特征在于,所述客户机应用程序向所述数据库服务器提交上下文信息,所述上下文信息包括容器引用,和到所述指定成员的单独成员路径,以及将上下文信息标识成到所述数据存储中所述指定成员的位置的路径的元数据注释。全文摘要若干用户定义类型的成员可指定为可延迟的成员。在该类型的初始取出期间,可从数据库返回该类型而不带可延迟的成员,从而保护了有用的带宽并减少了完成初始取出需要的时间量。在请求之后,在以后时间可从数据库再取出被选择的可延迟成员而不必返回在初始取出期间提供的其它成员。文档编号G06F7/00GK1716249SQ20051007547公开日2006年1月4日申请日期2005年5月31日优先权日2004年6月29日发明者C·克莱纳曼,E·扎博克里茨基,G·S·克里希纳莫里斯,G·奈尔,S·阿什威申请人:微软公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1