13.07.2015 Views

Using the Caché Managed Provider for .NET - InterSystems ...

Using the Caché Managed Provider for .NET - InterSystems ...

Using the Caché Managed Provider for .NET - InterSystems ...

SHOW MORE
SHOW LESS
  • No tags were found...

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

<strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong><strong>Provider</strong> <strong>for</strong> .<strong>NET</strong>Version 2008.210 October 2008<strong>InterSystems</strong> Corporation 1 Memorial Drive Cambridge MA 02142 www.intersystems.com


<strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong><strong>Caché</strong> Version 2008.2 10 October 2008Copyright © 2008 <strong>InterSystems</strong> CorporationAll rights reserved.This book was assembled and <strong>for</strong>matted in Adobe Page Description Format (PDF) using tools and in<strong>for</strong>mation from<strong>the</strong> following sources: Sun Microsystems, RenderX, Inc., Adobe Systems, and <strong>the</strong> World Wide Web Consortium atwww.w3c.org. The primary document development tools were special-purpose XML-processing applications builtby <strong>InterSystems</strong> using <strong>Caché</strong> and Java.and<strong>Caché</strong> WEBLINK, Distributed Cache Protocol, M/SQL, N/<strong>NET</strong>, and M/PACT are registered trademarks of <strong>InterSystems</strong>Corporation.and<strong>InterSystems</strong> TrakCare, <strong>InterSystems</strong> Jalapeño Technology, Enterprise Cache Protocol, ECP, and <strong>InterSystems</strong>Zen are trademarks of <strong>InterSystems</strong> Corporation.All o<strong>the</strong>r brand or product names used herein are trademarks or registered trademarks of <strong>the</strong>ir respective companiesor organizations.This document contains trade secret and confidential in<strong>for</strong>mation which is <strong>the</strong> property of <strong>InterSystems</strong> Corporation,One Memorial Drive, Cambridge, MA 02142, or its affiliates, and is furnished <strong>for</strong> <strong>the</strong> sole purpose of <strong>the</strong> operationand maintenance of <strong>the</strong> products of <strong>InterSystems</strong> Corporation. No part of this publication is to be used <strong>for</strong> any o<strong>the</strong>rpurpose, and this publication is not to be reproduced, copied, disclosed, transmitted, stored in a retrieval system ortranslated into any human or computer language, in any <strong>for</strong>m, by any means, in whole or in part, without <strong>the</strong> expressprior written consent of <strong>InterSystems</strong> Corporation.The copying, use and disposition of this document and <strong>the</strong> software programs described herein is prohibited exceptto <strong>the</strong> limited extent set <strong>for</strong>th in <strong>the</strong> standard software license agreement(s) of <strong>InterSystems</strong> Corporation coveringsuch programs and related documentation. <strong>InterSystems</strong> Corporation makes no representations and warrantiesconcerning such software programs o<strong>the</strong>r than those set <strong>for</strong>th in such standard software license agreement(s). Inaddition, <strong>the</strong> liability of <strong>InterSystems</strong> Corporation <strong>for</strong> any losses or damages relating to or arising out of <strong>the</strong> use ofsuch software programs is limited in <strong>the</strong> manner set <strong>for</strong>th in such standard software license agreement(s).THE FOREGOING IS A GENERAL SUMMARY OF THE RESTRICTIONS AND LIMITATIONS IMPOSED BYINTERSYSTEMS CORPORATION ON THE USE OF, AND LIABILITY ARISING FROM, ITS COMPUTERSOFTWARE. FOR COMPLETE INFORMATION REFERENCE SHOULD BE MADE TO THE STANDARD SOFTWARELICENSE AGREEMENT(S) OF INTERSYSTEMS CORPORATION, COPIES OF WHICH WILL BE MADE AVAILABLEUPON REQUEST.<strong>InterSystems</strong> Corporation disclaims responsibility <strong>for</strong> errors which may appear in this document, and it reserves <strong>the</strong>right, in its sole discretion and without notice, to make substitutions and modifications in <strong>the</strong> products and practicesdescribed in this document.For Support questions about any <strong>InterSystems</strong> products, contact:<strong>InterSystems</strong> Worldwide Customer SupportTel: +1 617 621-0700Fax: +1 617 374-9391Email: support@<strong>InterSystems</strong>.com


Table of Contents1 The <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> Solution ....................................................................................... 11.1 <strong>Caché</strong> .<strong>NET</strong> Binding Architecture ......................................................................................... 21.1.1 Software Requirements ................................................................................................ 31.2 The <strong>Caché</strong> .<strong>NET</strong> Sample Programs ....................................................................................... 42 Setting Up <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> ..................................................................................... 72.1 Setting up a New <strong>Caché</strong> <strong>Provider</strong> .<strong>NET</strong> Project .................................................................... 72.2 Adding <strong>the</strong> <strong>Caché</strong> Object Binding Wizard to Visual Studio .................................................. 92.3 Installing Cache<strong>Provider</strong> Help ............................................................................................. 103 Connecting to <strong>the</strong> <strong>Caché</strong> Database ............................................................................................. 113.1 Creating a Connection .......................................................................................................... 113.2 Connection Pooling .............................................................................................................. 123.2.1 <strong>Using</strong> <strong>the</strong> CachePoolManager Class .......................................................................... 133.3 <strong>Caché</strong> Server Configuration ................................................................................................. 153.4 Connection Parameters ........................................................................................................ 163.4.1 Required Parameters .................................................................................................. 163.4.2 Connection Pooling Parameters ................................................................................. 163.4.3 O<strong>the</strong>r Connection Parameters .................................................................................... 174 <strong>Using</strong> <strong>Caché</strong> ADO <strong>Provider</strong> Classes ........................................................................................... 194.1 Introduction to ADO <strong>Provider</strong> Classes ................................................................................. 204.1.1 Overview of <strong>Caché</strong> ADO <strong>Provider</strong> Classes ............................................................... 214.2 <strong>Using</strong> CacheCommand and CacheDataReader .................................................................... 214.3 <strong>Using</strong> SQL Queries with CacheParameter ........................................................................... 224.4 <strong>Using</strong> Transactions ............................................................................................................... 235 <strong>Using</strong> <strong>Caché</strong> Proxy Classes .......................................................................................................... 255.1 Introduction to Proxy Objects .............................................................................................. 265.2 Generating <strong>Caché</strong> Proxy Classes ......................................................................................... 275.2.1 <strong>Using</strong> <strong>the</strong> <strong>Caché</strong> Object Binding Wizard ................................................................... 285.2.2 Running dotnet_generator.exe from <strong>the</strong> Command Line ........................................... 305.2.3 Generating Proxy Files Programmatically ................................................................. 325.2.4 Adding Proxy Code to a Project ................................................................................ 345.2.5 Methods Inherited from <strong>Caché</strong> System Classes ........................................................ 355.3 <strong>Using</strong> Proxy Objects ............................................................................................................ 375.3.1 Opening and Reading Objects ................................................................................... 375.3.2 Creating and Saving Objects ...................................................................................... 375.3.3 Closing and Deleting Objects .................................................................................... 38<strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong>iii


5.4 <strong>Using</strong> <strong>Caché</strong> Queries ............................................................................................................ 395.5 <strong>Using</strong> Collections ................................................................................................................. 405.6 <strong>Using</strong> Relationships ............................................................................................................. 405.7 <strong>Using</strong> I/O Redirection .......................................................................................................... 416 <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> Class Reference ................................................................................ 436.1 The CacheClient Namespace ............................................................................................... 436.1.1 Connection and Command Classes ........................................................................... 446.1.2 Reader and Adapter Classes ....................................................................................... 446.2 The CacheTypes Namespace ................................................................................................ 446.2.1 <strong>Caché</strong> Object Classes ................................................................................................. 456.2.2 <strong>Caché</strong> Collection Classes ........................................................................................... 466.2.3 Date and Time Structs ................................................................................................ 476.2.4 Exception Classes ...................................................................................................... 476.2.5 Stream Classes ........................................................................................................... 486.2.6 SysList Classes .......................................................................................................... 48iv<strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong>


List of Figures<strong>Caché</strong> .<strong>NET</strong> Binding Client/Server Architecture ................................................................................ 3<strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong>v


List of TablesRequired Parameters ......................................................................................................................... 16Connection Pooling Parameters ........................................................................................................ 17O<strong>the</strong>r Connection Parameters ............................................................................................................ 17vi<strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong>


1The <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong>SolutionThe <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong> provides an easy and efficient way to make use of <strong>Caché</strong> from.<strong>NET</strong> applications. The <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> is unique in that it offers simultaneous relationaland object access to data using a common API and without requiring any object-to-relational mapping.The <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> provides <strong>the</strong> following features:• It provides complete, relational access to data using <strong>the</strong> ADO.<strong>NET</strong> API.• It offers high-per<strong>for</strong>mance native object access to data using auto-generated proxy classes. Theseproxy classes correspond to persistent objects stored within <strong>the</strong> <strong>Caché</strong> database and provide objectpersistence, retrieval, data caching, and life-cycle management.• It is implemented using .<strong>NET</strong> managed code throughout, making it easy to deploy within a .<strong>NET</strong>environment.• It is thread-safe and can be used within multithreaded .<strong>NET</strong> applications.Contents of this manualThe following chapters will introduce you to <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong>:• Setting up <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> gives you detailed instructions <strong>for</strong> <strong>the</strong> common tasksinvolved in setting up any .<strong>NET</strong> project that will use <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong>.• Connecting to <strong>the</strong> <strong>Caché</strong> Database provides detailed in<strong>for</strong>mation about database connections(including connection pooling) relevant to both ADO and native object access.• <strong>Using</strong> ADO <strong>Provider</strong> Classes gives concrete examples using <strong>the</strong> <strong>Caché</strong> implementation of <strong>the</strong>.<strong>NET</strong> ADO <strong>Provider</strong> classes.<strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong> 1


The <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> Solution• <strong>Using</strong> <strong>Caché</strong> Proxy Classes provides instructions <strong>for</strong> creating proxy classes, and gives concreteexamples of how to use proxy objects in your code.• <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> Class Reference provides details on <strong>the</strong> classes and methods availablewith <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong>.Throughout this document, we use code examples taken from <strong>the</strong> bookdemos project located in\Dev\dotnet\samples\bookdemos (see Default <strong>Caché</strong> Installation Directory <strong>for</strong> <strong>the</strong>location of on your system). For details on how to set up and run this and o<strong>the</strong>rsample programs, see The <strong>Caché</strong> .<strong>NET</strong> Sample Programs.Web Services (SOAP) can also be used to exchange data between <strong>Caché</strong> and .<strong>NET</strong> client applications.For more in<strong>for</strong>mation, refer to <strong>the</strong> following online documents:• <strong>Using</strong> SOAP and Web Services with <strong>Caché</strong> in <strong>the</strong> <strong>Caché</strong> Language Bindings section.• <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong> Tutorial in <strong>the</strong> <strong>Caché</strong> Tutorials section.1.1 <strong>Caché</strong> .<strong>NET</strong> Binding ArchitectureThe <strong>Caché</strong> .<strong>NET</strong> binding gives .<strong>NET</strong> applications a way to interoperate with objects contained withina <strong>Caché</strong> server. These objects can be persistent objects stored within <strong>the</strong> <strong>Caché</strong> object database or <strong>the</strong>ycan be transient objects that per<strong>for</strong>m operations within a <strong>Caché</strong> server.The <strong>Caché</strong> .<strong>NET</strong> Binding consists of <strong>the</strong> following components:• The <strong>Caché</strong> Object Server — a high per<strong>for</strong>mance server process that manages communicationbetween .<strong>NET</strong> objects and a <strong>Caché</strong> database server using standard networking protocols (TCP/IP).<strong>Caché</strong> uses a common server <strong>for</strong> .<strong>NET</strong>, C++, Java, Perl, Python, ODBC, and JDBC access.• The <strong>InterSystems</strong>.Data.CacheClient assembly — a set of .<strong>NET</strong> classes that implement all <strong>the</strong>functionality of <strong>the</strong> .<strong>NET</strong> classes created by <strong>the</strong> <strong>Caché</strong> Proxy Generator. It also provides a set ofproxy classes <strong>for</strong> a few Object Server classes that are projected differently to make <strong>the</strong>m fit into<strong>the</strong> framework of <strong>the</strong> .<strong>NET</strong> standard library.• The <strong>Caché</strong> Proxy Generator — a set of methods that generate .<strong>NET</strong> classes (source files or completeassemblies) from classes defined in <strong>the</strong> <strong>Caché</strong> Class Dictionary. Several different interfaces areavailable (see Generating <strong>Caché</strong> Proxy Classes).The Proxy Generator can create .<strong>NET</strong> proxy classes <strong>for</strong> any class in <strong>the</strong> <strong>Caché</strong> Class Dictionary. Theproxy classes contain only managed .<strong>NET</strong> code, which <strong>the</strong> Proxy Generator creates by inspecting <strong>the</strong>class definitions found in <strong>the</strong> <strong>Caché</strong> Class Dictionary. Instances of <strong>the</strong> .<strong>NET</strong> proxy classes on <strong>the</strong> clientcommunicate at runtime (using TCP/IP sockets) with <strong>the</strong>ir corresponding <strong>Caché</strong> objects on a <strong>Caché</strong>server. This is illustrated in <strong>the</strong> following diagram:2 <strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong>


<strong>Caché</strong> .<strong>NET</strong> Binding Client/Server Architecture<strong>Caché</strong> .<strong>NET</strong> Binding ArchitectureThe basic mechanism works as follows:• You define one or more classes within <strong>Caché</strong>. These can be persistent objects stored within <strong>the</strong><strong>Caché</strong> database or transient objects that run within a <strong>Caché</strong> server.• The <strong>Caché</strong> Proxy Generator creates .<strong>NET</strong> proxy classes that correspond to your <strong>Caché</strong> classes.These classes contain stub methods and properties that correspond to <strong>Caché</strong> object methods andproperties on <strong>the</strong> server.• At runtime, your .<strong>NET</strong> application connects to a <strong>Caché</strong> server. It can <strong>the</strong>n create instances of .<strong>NET</strong>proxy objects that correspond to objects within <strong>the</strong> <strong>Caché</strong> server. You can use <strong>the</strong>se proxy objectsas you would any o<strong>the</strong>r .<strong>NET</strong> objects. <strong>Caché</strong> automatically manages all communications as wellas client-side data caching.The runtime architecture consists of <strong>the</strong> following:• A <strong>Caché</strong> database server (or servers).• A .<strong>NET</strong> client application into which your generated and compiled .<strong>NET</strong> proxy classes have beenlinked.At runtime, <strong>the</strong> .<strong>NET</strong> application connects to <strong>Caché</strong> using an object connection interface (providedby <strong>the</strong> CacheConnection class). All communication between <strong>the</strong> .<strong>NET</strong> application and <strong>the</strong> <strong>Caché</strong> serveruses <strong>the</strong> standard TCP/IP protocol.1.1.1 Software RequirementsThe <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> requires <strong>the</strong> following development environment:• <strong>Caché</strong> 5.1 or higher• Visual Studio 2005• .<strong>NET</strong> Framework 2.0<strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong> 3


The <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> Solution<strong>Caché</strong> is not required on computers that run your <strong>Caché</strong> .<strong>NET</strong> client applications, but <strong>the</strong>y must have.<strong>NET</strong> Framework 2.0 and a TCP/IP connection to <strong>the</strong> <strong>Caché</strong> Server.1.2 The <strong>Caché</strong> .<strong>NET</strong> Sample Programs<strong>Caché</strong> comes with a set of sample projects that demonstrate <strong>the</strong> use of <strong>the</strong> <strong>Caché</strong> .<strong>NET</strong> binding. Thesesamples are located in <strong>the</strong> /dev/dotnet/samples/ subdirectory of <strong>the</strong> <strong>Caché</strong> installation(see Default <strong>Caché</strong> Installation Directory in <strong>the</strong> <strong>Caché</strong> Installation Guide <strong>for</strong> <strong>the</strong> location of on your system).• ado<strong>for</strong>m — A simple program to access and manipulate <strong>the</strong> Sample.Person database. The sameprogram is presented in three different Visual Studio languages: C#, Basic, and C++.• bookdemos — Contains complete, working versions of <strong>the</strong> examples in this document. The projectis a small, easily modified test bed <strong>for</strong> short sample routines. All of <strong>the</strong> relevant sample code isin one file: SampleCode.cs.Be<strong>for</strong>e running this demo, you must regenerate <strong>the</strong> ..\bookdemos\WizardCode.cs file, which containsproxy classes <strong>for</strong> <strong>the</strong> Sample package (see Generating <strong>Caché</strong> Proxy Classes <strong>for</strong> detailed instructions).• console — A console program that demonstrates <strong>the</strong> bare minimum requirements <strong>for</strong> a <strong>Caché</strong>.<strong>NET</strong> project.• mobiledevice — Similar to ado<strong>for</strong>m, but demonstrates how <strong>the</strong> mobile version of <strong>the</strong> CacheClientassembly deals with transient connections.• objbind — Similar to ado<strong>for</strong>m, but demonstrates how to write code that uses both ADO <strong>Provider</strong>objects and <strong>Caché</strong> proxy objects in a complementary fashion.Be<strong>for</strong>e running this demo, you must regenerate <strong>the</strong> SampleExport.cs file, which contains proxyclasses <strong>for</strong> <strong>the</strong> Sample package (follow <strong>the</strong> instructions in Generating <strong>Caché</strong> Proxy Classes, butset <strong>the</strong> output file to ..\objbind\SampleExport.cs ra<strong>the</strong>r than ..\bookdemos\WizardCode.cs).All of <strong>the</strong>se projects use classes from <strong>the</strong> Sample package in <strong>the</strong> SAMPLES namespace. You can use<strong>Caché</strong> Studio to examine <strong>the</strong> ObjectScript code <strong>for</strong> <strong>the</strong>se classes.Important:Always make sure that you have generated proxy class files <strong>for</strong> <strong>the</strong> latest version of<strong>the</strong> classes in <strong>the</strong> Sample package (see Generating <strong>Caché</strong> Proxy Classes <strong>for</strong> detailedinstructions). A mismatch between <strong>Caché</strong> classes and <strong>the</strong>ir proxy classes will causeyour program to fail. As mentioned previously, new proxy class files must be generated<strong>for</strong> <strong>the</strong> bookdemos and objbind projects.4 <strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong>


The <strong>Caché</strong> .<strong>NET</strong> Sample ProgramsNote:Most of <strong>the</strong>se samples are written only in C#. If you decide to convert a sample to VisualBasic, bear in mind that a new Visual Basic .<strong>NET</strong> project will have a default namespace thatcontains every class defined by <strong>the</strong> project. If this is ignored, code such as:Dim p As New Sample.Personp = p.OpenId(CacheConnection, "1")will fail because <strong>the</strong> root namespace has not been referenced. This can be easily correctedby disabling <strong>the</strong> "Root namespace" option in <strong>the</strong> project preferences.<strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong> 5


2Setting Up <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong><strong>Provider</strong>This chapter describes how to set up a <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> .<strong>NET</strong> project, and how to add <strong>the</strong><strong>Caché</strong> Object Binding Wizard and <strong>the</strong> Cache<strong>Provider</strong> Help to Visual Studio 2005. The followingtopics are covered:• Setting up a New <strong>Caché</strong> <strong>Provider</strong> .<strong>NET</strong> Project — describes how to add <strong>the</strong> required assemblyreference and <strong>Using</strong> statements.• Adding <strong>the</strong> <strong>Caché</strong> Object Binding Wizard to Visual Studio — describes how to add a tool <strong>for</strong>creating <strong>Caché</strong> proxy objects to <strong>the</strong> Visual Studio Tools menu.• Installing Cache<strong>Provider</strong> Help — describes how to install Visual Studio context-sensitive (F1key) help <strong>for</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> classes.2.1 Setting up a New <strong>Caché</strong> <strong>Provider</strong> .<strong>NET</strong>ProjectThe <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> assembly (<strong>InterSystems</strong>.Data.CacheClient.dll) is installed along with <strong>the</strong>rest of <strong>Caché</strong>, and requires no special preparation. To use <strong>the</strong> <strong>Provider</strong> in a .<strong>NET</strong> project, you mustadd a reference to <strong>the</strong> assembly, and add <strong>the</strong> corresponding <strong>Using</strong> statements to your code.Add a Reference to <strong>the</strong> <strong>Caché</strong> <strong>Provider</strong>To add <strong>the</strong> <strong>Caché</strong> <strong>Provider</strong> to a project:1. From <strong>the</strong> Visual Studio 2005 main menu, select Project > Add Reference<strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong> 7


Setting Up <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong>2. In <strong>the</strong> Add Reference window, click on Browse...3. Browse to \Dev\dotnet\Bin and select <strong>InterSystems</strong>.Data.CacheClient.dll (seeDefault <strong>Caché</strong> Installation Directory in <strong>the</strong> <strong>Caché</strong> Installation Guide <strong>for</strong> <strong>the</strong> location of on your system).4. Click OK.In <strong>the</strong> Visual Studio Solution Explorer, <strong>the</strong> <strong>InterSystems</strong>.Data.CacheClient assembly should nowbe listed under References:Add <strong>Using</strong> Statements to <strong>the</strong> ApplicationAdd <strong>the</strong> <strong>Using</strong> statements <strong>for</strong> <strong>the</strong> <strong>Caché</strong> <strong>Provider</strong> be<strong>for</strong>e <strong>the</strong> beginning of your application's namespace.Both CacheClient and CacheTypes are included in <strong>the</strong> <strong>InterSystems</strong>.Data.CacheClient assembly.using <strong>InterSystems</strong>.Data.CacheClient;using <strong>InterSystems</strong>.Data.CacheTypes;namespace DotNetSample {...}8 <strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong>


Adding <strong>the</strong> <strong>Caché</strong> Object Binding Wizard to Visual StudioCacheTypes is not strictly necessary except when your project uses <strong>the</strong> classes listed in The CacheTypesNamespace, but both <strong>Using</strong> statements should be added as a matter of course, since you will probablyneed <strong>the</strong> CacheTypes classes sooner or later.2.2 Adding <strong>the</strong> <strong>Caché</strong> Object Binding Wizard toVisual StudioThe <strong>Caché</strong> Object Binding Wizard is a program to generate <strong>Caché</strong> proxy objects (see <strong>Using</strong> <strong>the</strong> <strong>Caché</strong>Object Binding Wizard in <strong>Using</strong> <strong>Caché</strong> Proxy Classes). It can be run from <strong>the</strong> command line, but willbe more readily available if you integrate it into Visual Studio by adding it to <strong>the</strong> External Toolsmenu.To add <strong>the</strong> <strong>Caché</strong> Object Binding Wizard to <strong>the</strong> Tools menu:1. From <strong>the</strong> Visual Studio main menu, select Tools > External Tools...2. In <strong>the</strong> External Tools window:• click Add• in <strong>the</strong> Title field, enter : Cache Object Binding Wizard• in <strong>the</strong> Command field, browse to <strong>the</strong> \Dev\dotnet\Bin directory and selectCacheNetWizard.exe (see Default <strong>Caché</strong> Installation Directory in <strong>the</strong> <strong>Caché</strong> Installation Guide<strong>for</strong> <strong>the</strong> location of on your system)• Click OK<strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong> 9


Setting Up <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong>The <strong>Caché</strong> Object Binding Wizard now will be displayed as an option on <strong>the</strong> Visual Studio Toolsmenu.2.3 Installing Cache<strong>Provider</strong> HelpThe Cache<strong>Provider</strong> help file provides detailed documentation <strong>for</strong> <strong>the</strong> classes in <strong>the</strong> <strong>Caché</strong> <strong>Provider</strong>API. It is available as a stand-alone help file (Cache<strong>Provider</strong>.chm in \Dev\dotnet\help),but it can also be integrated with Visual Studio to enable context-sensitive (F1 key) help.The installation file is Cache<strong>Provider</strong>HelpInstaller.msi, in \Dev\dotnet\help. To install,just run <strong>the</strong> installation file and follow <strong>the</strong> instructions provided by <strong>the</strong> installer. You may need toreboot be<strong>for</strong>e <strong>the</strong> new help files become available in Visual Studio.10 <strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong>


3Connecting to <strong>the</strong> <strong>Caché</strong> DatabaseThis chapter describes how to create a connection between your client application and <strong>the</strong> <strong>Caché</strong> Serverusing a CacheConnection object. Such connections are used by both <strong>Caché</strong> proxy classes and ADO<strong>Provider</strong> classes3.1 Creating a ConnectionOne of <strong>the</strong> most basic functions of <strong>the</strong> <strong>Caché</strong> <strong>Provider</strong> is to create a connection to a <strong>Caché</strong> database.The code below establishes a connection to <strong>the</strong> SAMPLES namespace used by most <strong>Caché</strong> sampleprograms (see The <strong>Caché</strong> .<strong>NET</strong> Sample Programs <strong>for</strong> details). The connection object is usable by anyclass that requires a <strong>Caché</strong> connection, regardless of whe<strong>the</strong>r you are using <strong>Caché</strong> proxy classes, ADO<strong>Provider</strong> classes, or both. See Connection Parameters <strong>for</strong> a complete list of parameters that can be usedwhen instantiating a connection object.Add Code to Instantiate <strong>the</strong> <strong>Caché</strong> ConnectionThe following simple method could be called to start a connection:public CacheConnection CacheConnect;private void CreateConnection(){try {CacheConnect = new CacheConnection();CacheConnect.ConnectionString ="Server=localhost; Port=1972; Namespace=SAMPLES;"+ "Password=SYS; User ID=_SYSTEM;";CacheConnect.Open();}catch (Exception eConn){MessageBox.Show("CreateConnection error: " + eConn.Message);}}<strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong> 11


Connecting to <strong>the</strong> <strong>Caché</strong> DatabaseThis example defines <strong>the</strong> CacheConnection object as a global that can be used anywhere in <strong>the</strong> program.Once <strong>the</strong> object has been created, it can be shared among all <strong>the</strong> ADO <strong>Provider</strong> classes and <strong>Caché</strong>proxy classes that need it. The connection object can be opened and closed as necessary. You can dothis explicitly by using CacheConnect.Open() and CacheConnect.Close(). If you are using an ADODataset, your DataAdapters will open and close <strong>the</strong> connection automatically, as needed.Use <strong>the</strong> CacheConnection.ConnectDlg() MethodYou can also prompt <strong>the</strong> user <strong>for</strong> a connection string. The previous example could be rewritten asfollows:private void CreateConnection(){try {CacheConnect = new CacheConnection();CacheConnect.ConnectionString = CacheConnection.ConnectDlg();CacheConnect.Open();}...The ConnectDlg() method displays <strong>the</strong> standard <strong>Caché</strong> connection dialog and returns <strong>the</strong> user's inputas a connection string.3.2 Connection PoolingConnection pooling is on by default. The following connection string parameters can be used to controlvarious aspects of connection pooling:• Pooling — Defaults to true. Set Pooling to false to create a connection with no connectionpooling.• Max Pool Size and Min Pool Size — Default values are 0 and 100. Set <strong>the</strong>se parametersto specify <strong>the</strong> maximum and minimum (initial) size of <strong>the</strong> connection pool <strong>for</strong> this specific connectionstring.• Connection Reset and Connection Lifetime — Set Connection Reset to true toturn on <strong>the</strong> pooled connection reset mechanism. Connection Lifetime specifies <strong>the</strong> numberof seconds to wait be<strong>for</strong>e resetting an idle pooled connection. The default value is 0.For example, <strong>the</strong> following connect string sets <strong>the</strong> initial size of <strong>the</strong> connection pool to 2 and <strong>the</strong>maximum number of connections to 5, and activates connection reset with a maximum connectionidle time of 3 seconds:12 <strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong>


Connection PoolingCacheConnect.ConnectionString ="Server = localhost;"+ " Port = 1972;"+ " Namespace = SAMPLES;"+ " Password = SYS;"+ " User ID = _SYSTEM;"+ " Min Pool Size = 2;"+ " Max Pool Size = 5;"+ " Connection Reset = true;"+ " Connection Lifetime = 3;";The CacheConnection class also includes <strong>the</strong> following static methods that can be used to controlpooling:ClearPool(conn)ClearAllPools()CacheConnection.ClearPool(conn);Clears <strong>the</strong> connection pool associated with connection conn.CacheConnection.ClearAllPools();Removes all connections in <strong>the</strong> connection pools and clears <strong>the</strong> pools.See <strong>Using</strong> <strong>the</strong> CachePoolManager Class <strong>for</strong> o<strong>the</strong>r ways to control connection pooling programmatically.3.2.1 <strong>Using</strong> <strong>the</strong> CachePoolManager ClassThe CacheClient.CachePoolManager class can be used to monitor and control connection poolingprogrammatically. The following static methods are available:ActiveConnectionCountIdleCount()int count = CachePoolManager.ActiveConnectionCount;Total number of established connections in all pools. Count includes both idle and in-useconnections.int count = CachePoolManager.IdleCount();Total number of idle connections in all <strong>the</strong> pools.IdleCount(conn)int count = CachePoolManager.IdleCount(conn);<strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong> 13


Connecting to <strong>the</strong> <strong>Caché</strong> DatabaseInUseCount()Total number of idle connections in <strong>the</strong> pool associated with connection object conn.int count = CachePoolManager.InUseCount();Total number of in-use connections in all pools.InUseCount(conn)int count = CachePoolManager.InUseCount(conn);Total number of in-use connections in <strong>the</strong> pool associated with connection object conn.RecycleAllConnections(Boolean)CachePoolManager.RecycleAllConnections(bool remove);Recycles connections in all poolsRecycleConnections(conn, Boolean)CachePoolManager.RecycleConnections(conn,bool remove)Recycles connections in <strong>the</strong> pool associated with connection object conn.RemoveAllIdleConnections()CachePoolManager.RemoveAllIdleConnections();Removes idle connections from all connection pools.RemoveAllPoolConnections()CachePoolManager.RemoveAllPoolConnections();Deletes all connections and removes all pools, regardless of what state <strong>the</strong> connections arein.For a working example that uses most of <strong>the</strong>se methods, see <strong>the</strong> Proxy_9_Connection_Pools() methodin <strong>the</strong> bookdemos sample program (see The <strong>Caché</strong> .<strong>NET</strong> Sample Programs).14 <strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong>


<strong>Caché</strong> Server Configuration3.3 <strong>Caché</strong> Server ConfigurationVery little configuration is required to use a .<strong>NET</strong> client with a <strong>Caché</strong> Server process. The sampleprograms provided with <strong>Caché</strong> should work with no change following a default <strong>Caché</strong> installation.This section describes <strong>the</strong> server settings required <strong>for</strong> a connection, and some troubleshooting tips.Every .<strong>NET</strong> client that wishes to connect to a <strong>Caché</strong> Server needs <strong>the</strong> following in<strong>for</strong>mation:• A URL that provides <strong>the</strong> server IP address, port number, and <strong>Caché</strong> namespace.• A case-sensitive user name and password.By default, <strong>the</strong> sample programs use <strong>the</strong> following connection in<strong>for</strong>mation:• connection string: "localhost[1972]:SAMPLES"• username: "_SYSTEM"• password: "SYS"Check <strong>the</strong> following points if you have any problems:• Make sure that <strong>the</strong> <strong>Caché</strong> Server process is installed and running.• Make sure that you know <strong>the</strong> IP address of <strong>the</strong> machine on which <strong>the</strong> <strong>Caché</strong> Server process isrunning. The sample programs use "localhost". If you want a sample program to default to adifferent system you will need to change <strong>the</strong> connection string in <strong>the</strong> code.• Make sure that you know <strong>the</strong> TCP/IP port number on which <strong>the</strong> <strong>Caché</strong> Server is listening. Thesample programs use "1972". If you want a sample program to default to a different port, youwill need change <strong>the</strong> number in <strong>the</strong> sample code.• Make sure that you have a valid user name and password to use to establish a connection. (Youcan manage user names and passwords using <strong>the</strong> <strong>Caché</strong> System Management Portal: [Home] >[Security Management] > [Users]). The sample programs use <strong>the</strong> administrator user name"_SYSTEM" and <strong>the</strong> default password "SYS". Typically, you will change <strong>the</strong> default passwordafter installing <strong>the</strong> server. If you want a sample program to default to a different user name andpassword, you will need to change <strong>the</strong> sample code.• Make sure that your connection URL includes a valid <strong>Caché</strong> namespace. This should be <strong>the</strong>namespace containing <strong>the</strong> classes and data your program uses. The samples connect to <strong>the</strong>SAMPLES namespace, which is pre-installed with <strong>Caché</strong>.<strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong> 15


Connecting to <strong>the</strong> <strong>Caché</strong> Database3.4 Connection ParametersThe following tables describe all parameters that can be used in a connection string.3.4.1 Required ParametersThe following five parameters are required <strong>for</strong> all connection strings (see Creating a Connection).Required ParametersNameSERVERPORTNAMESPACEPASSWORDUSER IDDescriptionIP address or host name. For example:Server = localhostalternate names: ADDR, ADDRESS, DATA SOURCE,<strong>NET</strong>WORK ADDRESSSpecifies <strong>the</strong> TCP/IP port number <strong>for</strong> <strong>the</strong> connection.For example:Port = 1972Specifies <strong>the</strong> namespace to connect to. For example:Namespace = SAMPLESalternate names: INITIAL CATALOG, DATABASEUser's password. For example:Password = SYSalternate name: PWDset user login name. For example:User ID = _SYSTEMalternate names: USER, UID3.4.2 Connection Pooling ParametersThe following parameters define various aspects of connection pooling (see Connection Pooling).16 <strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong>


Connection ParametersConnection Pooling ParametersNameCONNECTION LIFETIMECONNECTION RESETMAX POOL SIZEMIN POOL SIZEPOOLINGDescriptionThe length of time in seconds to wait be<strong>for</strong>e resettingan idle Pooled connection when <strong>the</strong> connection resetmechanism is on. Default is 0.Turn on Pooled connection reset mechanism (used withCONNECTION LIFETIME). Default is false.Maximum size of connection pool <strong>for</strong> this specificconnection string. Default is 100.Minimum or initial size of <strong>the</strong> connection pool, <strong>for</strong> thisspecific connection string. Default is 0.Turn on connection pooling. Default is true.3.4.3 O<strong>the</strong>r Connection ParametersThe following optional parameters can be set if required.O<strong>the</strong>r Connection ParametersNameAPPLICATION NAMECONNECTION TIMEOUTCURRENT LANGUAGELOGFILEPACKET SIZEPREPARSE CACHE SIZEQUERYTIMEOUTDescriptionSets <strong>the</strong> application name.Sets <strong>the</strong> length of time in seconds to try and establisha connection be<strong>for</strong>e failure. Default is 30.alternate name: CONNECT TIMEOUTSets <strong>the</strong> language <strong>for</strong> this process.Turns on logging and sets <strong>the</strong> log file location.alternate name: LOG FILE.Sets <strong>the</strong> TCP Packet size. Default is 1024.Sets an upper limit to <strong>the</strong> number of SQL commandsthat will be held in <strong>the</strong> preparse cache be<strong>for</strong>e recyclingis applied. Default is 200.Sets <strong>the</strong> length of time in seconds to attempt a querybe<strong>for</strong>e failure.alternate name: QUERY TIMEOUT<strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong> 17


Connecting to <strong>the</strong> <strong>Caché</strong> DatabaseNameSO RCVBUFSO SNDBUFTCP NODELAYTRANSACTION ISOLATIONLEVELWORKSTATION IDDescriptionSets <strong>the</strong> TCP receive buffer size. Default is 8760.alternate name: SO_RCVBUFSets <strong>the</strong> TCP send buffer size. Default is 8760.alternate name: SO_SNDBUFSets <strong>the</strong> TCP nodelay option. Default is true.alternate name: TCP_NODELAYSets <strong>the</strong> System.Data.IsolationLevel value <strong>for</strong> <strong>the</strong>connection.alternate name: TRANSACTIONISOLATIONLEVELSets <strong>the</strong> Workstation name <strong>for</strong> process identification.18 <strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong>


<strong>Using</strong> <strong>Caché</strong> ADO <strong>Provider</strong> Classes4.1 Introduction to ADO <strong>Provider</strong> ClassesA project using <strong>the</strong> <strong>Caché</strong> ADO <strong>Provider</strong> classes can be quite simple. Here is a complete, workingconsole program that opens and reads an item from <strong>the</strong> Sample.Person database:using System;using <strong>InterSystems</strong>.Data.CacheClient;using <strong>InterSystems</strong>.Data.CacheTypes;namespace TinySpace {class Tiny<strong>Provider</strong> {[STAThread]static void Main(string[] args) {}CacheConnection CacheConnect = new CacheConnection();CacheConnect.ConnectionString = "Server = localhost; "+ "Port = 1972; " + "Namespace = SAMPLES; "+ "Password = SYS; " + "User ID = _SYSTEM;";CacheConnect.Open();string SQLtext = "SELECT * FROM Sample.Person WHERE ID = 1";CacheCommand Command = new CacheCommand(SQLtext, CacheConnect);CacheDataReader Reader = Command.ExecuteReader();while (Reader.Read()) {Console.WriteLine("Tiny<strong>Provider</strong> output: \r\n "+ Reader[Reader.GetOrdinal("ID")] + ": "+ Reader[Reader.GetOrdinal("Name")]);};Reader.Close();Command.Dispose();CacheConnect.Close();} // end Main()} // end class Tiny<strong>Provider</strong>This project contains <strong>the</strong> following important features:• The <strong>Using</strong> statements provide access to <strong>the</strong> CacheClient assembly:using <strong>InterSystems</strong>.Data.CacheClient;using <strong>InterSystems</strong>.Data.CacheTypes;• The CacheConnection object is used to create and open a connection to <strong>the</strong> <strong>Caché</strong> SAMPLESnamespace:CacheConnection CacheConnect = new CacheConnection();CacheConnect.ConnectionString = "Server = localhost; "+ "Port = 1972; " + "Namespace = SAMPLES; "+ "Password = SYS; " + "User ID = _SYSTEM;";CacheConnect.Open();• The CacheCommand object uses <strong>the</strong> CacheConnection object and an SQL statement to open <strong>the</strong>instance of Sample.Person that has an ID equal to 1.string SQLtext = "SELECT * FROM Sample.Person WHERE ID = 1";CacheCommand Command = new CacheCommand(SQLtext, CacheConnect);20 <strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong>


• The CacheDataReader object is used to access <strong>the</strong> data items in <strong>the</strong> row:CacheDataReader Reader = Command.ExecuteReader();while (Reader.Read()) {Console.WriteLine("Tiny<strong>Provider</strong> output: \r\n "+ Reader[Reader.GetOrdinal("ID")] + ": "+ Reader[Reader.GetOrdinal("Name")]);};<strong>Using</strong> CacheCommand and CacheDataReader4.1.1 Overview of <strong>Caché</strong> ADO <strong>Provider</strong> ClassesThe following classes are <strong>Caché</strong>-specific versions of <strong>the</strong> standard ADO <strong>Provider</strong> classes:• CacheConnection — Represents <strong>the</strong> connection between your application and <strong>the</strong> databases in aspecified <strong>Caché</strong> namespace. Use of CacheConnection objects is described in detail in Connectingto <strong>the</strong> <strong>Caché</strong> Database.• CacheCommand — Encapsulates an SQL statement or stored procedure to be executed againstdatabases in <strong>the</strong> namespace specified by a CacheConnection.• CacheDataReader — Provides <strong>the</strong> means to fetch <strong>the</strong> resultset specified by a CacheCommand. ACacheDataReader object provides quick <strong>for</strong>ward-only access to <strong>the</strong> resultset, but is not designed<strong>for</strong> random access.• CacheDataAdapter — Encapsulates a resultset that is mapped to data in <strong>the</strong> namespace specifiedby a CacheConnection. It is used to fill an ADO DataSet and to update <strong>the</strong> <strong>Caché</strong> database, providingan effective random access connection to <strong>the</strong> resultset.4.2 <strong>Using</strong> CacheCommand andCacheDataReaderSimple read-only queries can be per<strong>for</strong>med using only CacheCommand and CacheDataReader. Likeall database transactions, such queries also require an open CacheConnection object.In this example, an SQL query string is passed to a new CacheCommand object, which will use <strong>the</strong>existing connection:string SQLtext = "SELECT * FROM Sample.Person WHERE ID < 10";CacheCommand Command = new CacheCommand(SQLtext, CacheConnect);Results of <strong>the</strong> query are returned in a CacheDataReader object. Properties are accessed by referringto <strong>the</strong> names of columns specified in <strong>the</strong> SQL statement.<strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong> 21


<strong>Using</strong> <strong>Caché</strong> ADO <strong>Provider</strong> ClassesCacheDataReader reader = Command.ExecuteReader();while (reader.Read()) {Display.WriteLine(reader[reader.GetOrdinal("ID")] + "\t"+ reader[reader.GetOrdinal("Name")] + "\r\n\t"+ reader[reader.GetOrdinal("Home_City")] + " "+ reader[reader.GetOrdinal("Home_State")] + "\r\n");};The same report could be generated using column numbers instead of names. Since CacheDataReaderobjects can only read <strong>for</strong>ward, <strong>the</strong> only way to return to beginning of <strong>the</strong> data stream is to close <strong>the</strong>reader and reopen it by executing <strong>the</strong> query again.reader.Close();reader = Command.ExecuteReader();while (reader.Read()) {Display.WriteLine(reader[0] + "\t"+ reader[4] + "\r\n\t"+ reader[7] + " "+ reader[8] + "\n");}For a working example, see <strong>the</strong> ADO_1_CommandReader() method in <strong>the</strong> bookdemos sample program(see The <strong>Caché</strong> .<strong>NET</strong> Sample Programs).4.3 <strong>Using</strong> SQL Queries with CacheParameterThe CacheParameter object is required <strong>for</strong> more complex SQL queries. The following example selectsdata from all rows where Name starts with a string specified by <strong>the</strong> CacheParameter value:string SQLtext ="SELECT ID, Name, DOB, SSN "+ "FROM Sample.Person "+ "WHERE Name %STARTSWITH ?"+ "ORDER BY Name";CacheCommand Command = new CacheCommand(SQLtext, CacheConnect);The parameter value is set to get all rows where Name starts with A, and <strong>the</strong> parameter is passed to <strong>the</strong>CacheCommand object:CacheParameter Name_param =new CacheParameter("Name_col", CacheDbType.NVarChar);Name_param.Value = "A";Command.Parameters.Add(Name_param);A CacheDataReader object can access <strong>the</strong> resulting data stream just as it did in <strong>the</strong> previous example:22 <strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong>


<strong>Using</strong> TransactionsCacheDataReader reader = Command.ExecuteReader();while (reader.Read()) {Display.WriteLine(reader[reader.GetOrdinal("ID")] + "\t"+ reader[reader.GetOrdinal("Name")] + "\r\n\t"+ reader[reader.GetOrdinal("DOB")] + " "+ reader[reader.GetOrdinal("SSN")] + "\r\n");};For a working example, see <strong>the</strong> ADO_2_Parameter() method in <strong>the</strong> bookdemos sample program (seeThe <strong>Caché</strong> .<strong>NET</strong> Sample Programs).The CacheCommand, CacheParameter, and CacheDataReader classes are also used to execute a <strong>Caché</strong>Query method from a proxy object. See <strong>Using</strong> <strong>Caché</strong> Queries <strong>for</strong> details.4.4 <strong>Using</strong> TransactionsThe Transaction class is used to specify an SQL transaction (see Transaction Processing in <strong>the</strong> “Modifying<strong>the</strong> Database” chapter of <strong>Using</strong> <strong>Caché</strong> SQL <strong>for</strong> a overview of how to use transactions with<strong>Caché</strong>). In <strong>the</strong> following example, transaction Trans will fail and be rolled back if SSN is not unique.CacheTransaction Trans =CacheConnect.BeginTransaction(System.Data.IsolationLevel.ReadCommitted);try {string SQLtext = "INSERT into Sample.Person(Name, SSN) Values(?,?)";CacheCommand Command = new CacheCommand(SQLtext, CacheConnect, Trans);CacheParameter Name_param =new CacheParameter("name", CacheDbType.NVarChar);Name_param.Value = "Rowe, Richard";Command.Parameters.Add(Name_param);CacheParameter SSN_param =new CacheParameter("ssn", CacheDbType.NVarChar);SSN_param.Value = "234-56-3454";Command.Parameters.Add(SSN_param);int rows = Command.ExecuteNonQuery();Trans.Commit();Display.WriteLine("Added record <strong>for</strong> " + SSN_param.Value.ToString());}catch (Exception eInsert) {Trans.Rollback();WriteErrorMessage("TransFail", eInsert);}For a working example, see <strong>the</strong> ADO_4_Transaction() method in <strong>the</strong> bookdemos sample program(see The <strong>Caché</strong> .<strong>NET</strong> Sample Programs).<strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong> 23


5<strong>Using</strong> <strong>Caché</strong> Proxy ClassesOne of <strong>the</strong> most important features of <strong>Caché</strong> is <strong>the</strong> ability to access database items as objects ra<strong>the</strong>rthan rows in relational tables. In <strong>Caché</strong> .<strong>NET</strong> Binding applications, this feature is implemented using<strong>Caché</strong> proxy objects. Proxy objects are instances of .<strong>NET</strong> classes (source files or complete assemblies)generated from classes defined in <strong>the</strong> <strong>Caché</strong> Class Dictionary. Each proxy object communicates witha corresponding object on <strong>the</strong> <strong>Caché</strong> server, and can be manipulated just as if it were <strong>the</strong> original object.The generated proxy classes are written in fully compliant .<strong>NET</strong> managed code, and can be used anywherein your project.This section gives some concrete examples of code using <strong>Caché</strong> proxy classes.• Introduction to Proxy Objects — a simple demonstration of how proxy objects are used.• Generating <strong>Caché</strong> Proxy Classes — using various tools to generate proxy classes.• <strong>Using</strong> <strong>Caché</strong> Proxy Objects — using proxy objects to create, open, alter, save, and delete objectson <strong>the</strong> <strong>Caché</strong> server.• <strong>Using</strong> <strong>Caché</strong> Queries — using a pre-existing <strong>Caché</strong> query to generate and manipulate a result set.• <strong>Using</strong> Collections — manipulating <strong>Caché</strong> lists and arrays.• <strong>Using</strong> Relationships — using <strong>Caché</strong> relationship objects to access and manipulate data sets.• <strong>Using</strong> I/O Redirection — redirecting <strong>Caché</strong> Read and Write statements.Although <strong>the</strong> examples in this chapter use only proxy objects to access <strong>Caché</strong> data, it is also possibleto access database instances via ADO classes and SQL statements, as described in <strong>Using</strong> <strong>Caché</strong> ADO<strong>Provider</strong> Classes. Both types of access can be used in <strong>the</strong> same program.<strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong> 25


<strong>Using</strong> <strong>Caché</strong> Proxy ClassesNote:The examples presented in this chapter are fragments from samples provided in <strong>the</strong> bookdemosproject (see The <strong>Caché</strong> .<strong>NET</strong> Sample Programs <strong>for</strong> details). It is assumed that you arefamiliar with standard coding practices, so <strong>the</strong> fragments omit error trapping (try/catch)statements and o<strong>the</strong>r code that is not directly relevant to <strong>the</strong> examples. For complete, workingversions of <strong>the</strong> code examples, see SampleCode.cs, located in\Dev\dotnet\samples\bookdemos (see Default <strong>Caché</strong> Installation Directoryin <strong>the</strong> <strong>Caché</strong> Installation Guide <strong>for</strong> <strong>the</strong> location of on your system).5.1 Introduction to Proxy ObjectsA <strong>Caché</strong> .<strong>NET</strong> project using proxy objects can be quite simple. Here is a complete, working consoleprogram that opens and reads an item from <strong>the</strong> Sample.Person database:using System;using <strong>InterSystems</strong>.Data.CacheClient;using <strong>InterSystems</strong>.Data.CacheTypes;namespace TinySpace {class TinyProxy {[STAThread]static void Main(string[] args) {}CacheConnection CacheConnect = new CacheConnection();CacheConnect.ConnectionString = "Server = localhost; "+ "Port = 1972; " + "Namespace = SAMPLES; "+ "Password = SYS; " + "User ID = _SYSTEM;";CacheConnect.Open();Sample.Person person = Sample.Person.OpenId(CacheConnect, "1");Console.WriteLine("TinyProxy output: \r\n "+ person.Id() + ": "+ person.Name);person.Close();CacheConnect.Close();} // end Main()} // end class TinyProxyThis project is almost identical to <strong>the</strong> one presented in <strong>Using</strong> <strong>Caché</strong> ADO <strong>Provider</strong> Classes (whichdoes not use proxy objects). Both projects contain <strong>the</strong> following important features:• The same <strong>Using</strong> statements provide access to <strong>the</strong> CacheClient assembly:using <strong>InterSystems</strong>.Data.CacheClient;using <strong>InterSystems</strong>.Data.CacheTypes;• The same code is used to create and open a connection to <strong>the</strong> <strong>Caché</strong> SAMPLES namespace:26 <strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong>


CacheConnection CacheConnect = new CacheConnection();CacheConnect.ConnectionString = "Server = localhost; "+ "Port = 1972; " + "Namespace = SAMPLES; "+ "Password = SYS; " + "User ID = _SYSTEM;";CacheConnect.Open();• Both projects have code to open and read <strong>the</strong> instance of Sample.Person that has an ID equalto 1.It differs from <strong>the</strong> ADO project in two significant ways:1. The project includes a file (WizardCode.cs) containing code <strong>for</strong> <strong>the</strong> generated proxy classes. SeeGenerating <strong>Caché</strong> Proxy Classes <strong>for</strong> a detailed description of how to generate this file and includeit in your project.2. The instance of Sample.Person is accessed through a Sample.Person proxy object ra<strong>the</strong>rthan CacheCommand and CacheDataReader objects.No SQL statement is needed. Instead, <strong>the</strong> connection and <strong>the</strong> desired instance are defined by acall to <strong>the</strong> OpenId() class method:Sample.Person person = Sample.Person.OpenId(CacheConnect, "1");Each data item in <strong>the</strong> instance is treated as a method or property that can be directly accessed withdot notation, ra<strong>the</strong>r than a data column to be accessed with CacheReader:Console.WriteLine("TinyProxy output: \r\n "+ person.Id() + ": "+ person.Name);Generating <strong>Caché</strong> Proxy ClassesIn many cases, code with proxy objects can be far simpler to write and maintain than <strong>the</strong> equivalentcode using ADO <strong>Provider</strong> objects. Your project can use both methods of access interchangeably,depending on which approach makes <strong>the</strong> most sense in any given situation.5.2 Generating <strong>Caché</strong> Proxy ClassesThis section covers <strong>the</strong> following topics:• <strong>Using</strong> <strong>the</strong> <strong>Caché</strong> Object Binding Wizard — a GUI program that leads you through <strong>the</strong> process ofgenerating proxy classes.• Running dotnet_generator from <strong>the</strong> Command Line — a DOS program that allows you to generateproxy classes from a batch file or an ANT script.• Generating Proxy Files Programmatically — calling <strong>the</strong> Proxy Generator methods directly tocreate proxy classes from within a .<strong>NET</strong> program.<strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong> 27


<strong>Using</strong> <strong>Caché</strong> Proxy Classes• Adding Proxy Code to a Project — what to do with new proxy files once you've got <strong>the</strong>m.• Methods Inherited from <strong>Caché</strong> System Classes — a set of standard methods that <strong>the</strong> Proxy Generatoradds to all proxy files.5.2.1 <strong>Using</strong> <strong>the</strong> <strong>Caché</strong> Object Binding WizardThe <strong>Caché</strong> Object Binding Wizard can be run ei<strong>the</strong>r as a stand-alone program (CacheNetWizard.exe,located in \Dev\dotnet\bin\ by default) or as a tool integrated into Visual Studio (SeeAdding <strong>the</strong> <strong>Caché</strong> Object Binding Wizard to Visual Studio).When you start <strong>the</strong> Wizard, <strong>the</strong> following window is displayed:Enter <strong>the</strong> following in<strong>for</strong>mation:1. Select <strong>the</strong> <strong>Caché</strong> server you wish to connect to:Select <strong>the</strong> server containing <strong>the</strong> <strong>Caché</strong> classes <strong>for</strong> which you want to generate .<strong>NET</strong> classes. Toselect <strong>the</strong> server:28 <strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong>


Generating <strong>Caché</strong> Proxy Classes• Click Connect and select your server• Enter your username and password at <strong>the</strong> prompt. The Cache Connection Manager isdisplayed:• Select <strong>the</strong> namespace containing your class (this will be SAMPLES <strong>for</strong> <strong>the</strong> bookdemos project)• Click OK.2. Select what you want <strong>the</strong> Wizard to generate:For <strong>the</strong> bookdemos project, you would select Source Files and Language: C#.3. Select where <strong>the</strong> Wizard output will go:Generally, this will be <strong>the</strong> same folder that contains <strong>the</strong> .csproj file <strong>for</strong> your project. In this example,<strong>the</strong> file will be named WizardCode.cs, and will be placed in <strong>the</strong> main bookdemos project directory.4. Select <strong>the</strong> classes you wish to use:For this exercise, you should select <strong>the</strong> Sample.Person and Sample.Company classes from<strong>the</strong> SAMPLES namespace. The Sample.Address and Sample.Employee classes will beincluded automatically because <strong>the</strong>y are used by Sample.Person and Sample.Company. Ifyou check Show System Classes, classes from %SYS (<strong>the</strong> standard <strong>Caché</strong> Class Library)will be displayed along with those from SAMPLES.5. Generator options:For this exercise, check Methods with default arguments and leave <strong>the</strong> o<strong>the</strong>r fieldsempty. The options are:• Use .Net Compact Framework — generate proxy code <strong>for</strong> mobile applications.• Methods with default arguments — generates some optional overloads <strong>for</strong> certain systemmethods.<strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong> 29


<strong>Using</strong> <strong>Caché</strong> Proxy Classes• Application Namespace — optional namespace that will be added to <strong>the</strong> names of all generatedproxy classes. For example, if you entered MyNamespace, <strong>the</strong> generated code would containreferences to MyNamespace.Sample.Person ra<strong>the</strong>r than just Sample.Person.6. Press 'Generate' to create classes:The generated file can now be added to your project (see Adding Proxy Code to a Project).5.2.2 Running dotnet_generator.exe from <strong>the</strong> Command LineThe command-line proxy generator program (dotnet_generator.exe, located in\Dev\dotnet\bin\by default) is useful when <strong>the</strong> same set of proxy files must be regenerated frequently. This is importantwhen <strong>the</strong> <strong>Caché</strong> classes are still under development, since <strong>the</strong> proxy classes must be regenerated everytime a <strong>Caché</strong> class is changed and compiled, even if <strong>the</strong> change does not affect <strong>the</strong> interface of <strong>the</strong>class.Required argumentsThe command-line generator always requires in<strong>for</strong>mation about <strong>the</strong> connection string, output path andtype of output file (cs, vb or dll), and a list of <strong>the</strong> classes to be generated. The following arguments areused:• -conn — standard connection string (see Creating a Connection).• If generating a single output file <strong>for</strong> all classes, use -path:- -path — path and name of <strong>the</strong> output file <strong>for</strong> <strong>the</strong> generated code.Type of output file to be generated is determined by extension of <strong>the</strong> filename (<strong>for</strong> example,C:\somepath\WizardCode.vb will generate a Visual Basic code file, whileC:\somepath\WizardCode.dll will generate an assembly).• If generating one output file <strong>for</strong> each class, use -dir and -src-kind:- -dir — directory where <strong>the</strong> generated proxy files will be placed.- -src-kind — type of proxy file to generate. For each class, a file named. will be generated in <strong>the</strong> directory specified by-dir. Options are cs or vb.• -class-list — path and name of a text file containing a list of <strong>the</strong>classes to be used. Each class name must be on a separate line.Optional argumentsThe following optional arguments are also available:30 <strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong>


• -gen-default-args — switch that controls generation of optionaloverloads to certain generated system methods. Options are true or false.• -app-nsp — optional namespace that will be added to <strong>the</strong> names of all generatedproxy classes. For example, if you entered MyNamespace, <strong>the</strong> generated code would containreferences to MyNamespace.Sample.Person ra<strong>the</strong>r than just Sample.Person..• -use-cf — switch that controls whe<strong>the</strong>r code is generated <strong>for</strong> mobiledevices or standard PCs. Options are true or false.• -sign-key — path and name of an assembly key file (only valid whengenerating a dll).ExampleThe DOS batch file in this example calls dotnet_generator three times, generating <strong>the</strong> following output:1. The first call generates a single file containing several proxy classes. This command generatesexactly <strong>the</strong> same WizardCode.cs file as <strong>the</strong> example in <strong>Using</strong> <strong>the</strong> <strong>Caché</strong> Object Binding Wizard.2. The second call generates one proxy file <strong>for</strong> each class, and generates Visual Basic code ra<strong>the</strong>rthan C#. The filenames will be of <strong>the</strong> <strong>for</strong>m .vb.3. The third call generates an assembly file, WizardCode.dll.All three calls use <strong>the</strong> same connection string, output directory, and class list file.set dotnetgen=C:\Intersystems\Cache\Dev\dotnet\bin\dotnet_generator.exeset listfile=C:\Intersystems\Cache\Dev\dotnet\samples\bookdemos\Classlist.txtset outputpath=C:\Intersystems\Cache\Dev\dotnet\samples\bookdemos\set connstring="Server=localhost;Port=1972;Namespace=SAMPLES;Password=SYS;UserID=_SYSTEM;"rem CALL #1: Generate a single WizardCode.cs proxy file%dotnetgen% -conn %connstring% -class-list %listfile% -path%outputpath%WizardCode.cs -gen-default-args truerem CALL #2: Generate one .vb proxy file <strong>for</strong> each class%dotnetgen% -conn %connstring% -class-list %listfile% -dir %outputpath% -src-kindvb -gen-default-args truerem CALL #3: Generate an assembly file%dotnetgen% -conn %connstring% -class-list %listfile% -path%outputpath%WizardCode.dll -gen-default-args trueThe contents of <strong>the</strong> class list file, Classlist.txt, are:Sample.CompanySample.PersonGenerating <strong>Caché</strong> Proxy ClassesAlthough only two classes are listed, proxy classes <strong>for</strong> Sample.Address and Sample.Employee aregenerated automatically because <strong>the</strong>y are used by Sample.Person and Sample.Company.<strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong> 31


<strong>Using</strong> <strong>Caché</strong> Proxy Classes5.2.3 Generating Proxy Files ProgrammaticallyThe CacheConnection class includes <strong>the</strong> following three methods that can be used to generate proxyfiles from within a .<strong>NET</strong> program:CacheConnection.GenSourceFile()Generates a new CS or VB proxy file that may contain definitions <strong>for</strong> several classes.CacheConnection.GenSourceFile(filepath, generator, classlist, options, errors);Parameters:• filepath — A string containing <strong>the</strong> path and filename of <strong>the</strong> file to be generated.• generator — An ICodeGenerator object that generates ei<strong>the</strong>r CS or VB code.• classlist — An IEnumerator iterator pointing to <strong>the</strong> list of classes that will be generated.• options — a GeneratorOptions object• errors — An IList array used to store any returned error messages.CacheConnection.GenMultipleSourceFiles()Generates a separate CS or VB proxy file named . <strong>for</strong> eachclass in classlist.CacheConnection.GenMultipleSourceFiles(dirpath, filetype, generator, classlist,options, errors);Parameters:• dirpath — A string containing <strong>the</strong> directory path <strong>for</strong> <strong>the</strong> files to be generated.• filetype — A string containing ei<strong>the</strong>r ".vb" or ".cs", depending on <strong>the</strong> code to begenerated.• generator — An ICodeGenerator object that generates ei<strong>the</strong>r CS or VB code.• classlist — An IEnumerator iterator pointing to <strong>the</strong> list of classes that will be generated.• options — A GeneratorOptions• errors — An IList array used to store any returned error messages.CacheConnection.GenAssembly()Generates an assembly file.32 <strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong>


CacheConnection.GenAssembly(filepath, keyfile, classlist, options, errors);Parameters:• filepath — A string containing <strong>the</strong> path and filename of <strong>the</strong> file to be generated.• keyfile — A string containing <strong>the</strong> path and filename of an assembly keyfile (may benull if no keyfile is used).• classlist — An IEnumerator iterator pointing to <strong>the</strong> list of classes that will be generated.• options — An ICodeGenerator object.• errors — An IList array used to store any returned error messages.For a working example that uses all three methods, see <strong>the</strong> Proxy_8_MakeProxyFiles() method in<strong>the</strong> bookdemos sample program (see The <strong>Caché</strong> .<strong>NET</strong> Sample Programs).5.2.3.1 <strong>Using</strong> <strong>the</strong> Proxy Generator MethodsThe following code fragments provide examples <strong>for</strong> defining <strong>the</strong> method parameters, and <strong>for</strong> callingeach of <strong>the</strong> three proxy generator methods.generator parameterThe generator can be ei<strong>the</strong>r a CSharpCode<strong>Provider</strong> or a VBCode<strong>Provider</strong>.System.CodeDom.Compiler.ICodeGenerator generatorclasslist parameterEach of <strong>the</strong> three methods accepts an iterator pointing to <strong>the</strong> list of classes to be generated. Althoughonly two classes are listed in <strong>the</strong> following example, proxy classes <strong>for</strong> Sample.Address andSample.Employee are generated automatically because <strong>the</strong>y are used by Sample.Person andSample.Company.ArrayList classes = new ArrayList();classes.Add("Sample.Company");classes.Add("Sample.Person");System.Collections.IEnumerator classlistclasslist = classes.GetEnumerator();options parameterGenerating <strong>Caché</strong> Proxy ClassesIn this example, no special namespace will be generated <strong>for</strong> <strong>the</strong> proxy code, a complete set of inheritedmethods will be generated <strong>for</strong> each class, and no extra code will be generated <strong>for</strong> use by mobileapplications.<strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong> 33


<strong>Using</strong> <strong>Caché</strong> Proxy Classes<strong>InterSystems</strong>.Data.CacheClient.ObjBind.GeneratorOptions optionsoptions = new GeneratorOptions();options.AppNamespace = "";options.GenDefaultArgMethods = true;options.UseCF = false;errors parameterThe errors parameter will store <strong>the</strong> error messages (if any) returned from <strong>the</strong> proxy generator methodcall. All three methods use this parameter.System.Collections.IList errorserrors = new System.Collections.ArrayList();Example 1: Generate a new CS proxy fileThis example generates a C# proxy file named WizardCode.cs in directory C:\MyApp\. The file willcontain code <strong>for</strong> Sample.Person, Sample.Company, Sample.Address, and Sample.Employee.string filepath = @"C:\MyApp\WizardCode.cs";generator = new CSharpCode<strong>Provider</strong>().CreateGenerator();conn.GenSourceFile(filepath, generator, classlist, options, errors);Example 2: Generate a set of single-class VB proxy filesThis example generates a single VB proxy file <strong>for</strong> each class.string dirpath = @"C:\MyApp\";string filetype = ".vb";generator = new VBCode<strong>Provider</strong>().CreateGenerator();conn.GenMultipleSourceFiles(dirpath, filetype, generator, classlist, options,errors);The following files will be generated in C:\MyApp\:Person.vbCompany.vbAddress.vbEmployee.vbThe proxy files <strong>for</strong> Sample.Address and Sample.Employee are generated automatically because <strong>the</strong>yare used by Sample.Person and Sample.Company.Example 3: Generate an assembly fileThis example generates an assembly named WizardCode_test.dll in directory C:\MyApp\. The keyfileparameter is set to null, indicating that we are not going to encrypt <strong>the</strong> assembly.string filepath = @"C:\MyApp\WizardCode.dll";string keyfile = null;conn.GenAssembly(filepath, keyfile, classlist, options, errors);5.2.4 Adding Proxy Code to a ProjectAfter generating .<strong>NET</strong> proxy files, add <strong>the</strong> code to your project as follows:34 <strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong>


• From <strong>the</strong> Visual Studio main menu, select Project > Add Existing Item...• Browse to <strong>the</strong> generated proxy file (or files, if you chose to generate one file <strong>for</strong> each class) andclick Add.The file will be listed in <strong>the</strong> Visual Studio Solution Explorer.Generating <strong>Caché</strong> Proxy ClassesYou can now use proxy objects as described in <strong>the</strong> following sections.Important:A generated proxy class is not updated automatically when you change <strong>the</strong> corresponding<strong>Caché</strong> class. You must always regenerate proxy classes whenever a change ismade in one of <strong>the</strong> <strong>Caché</strong> classes, even if <strong>the</strong> change does not affect <strong>the</strong> interface of<strong>the</strong> class. Any code change could cause <strong>the</strong> unsynchronized proxy classes to malfunctionin unpredictable ways.5.2.5 Methods Inherited from <strong>Caché</strong> System ClassesThe proxy file generators also provide proxy methods <strong>for</strong> certain classes inherited from <strong>the</strong> standard<strong>Caché</strong> Class Library. For example, <strong>the</strong> Sample classes inherit methods from <strong>Caché</strong> %Library.Persistentand %Library.Populate. Proxies <strong>for</strong> <strong>the</strong>se methods are automatically added when you generate <strong>the</strong> proxyfiles. This section provides a quick summary of <strong>the</strong> most commonly used methods. For more detailedin<strong>for</strong>mation on a method, see <strong>the</strong> entries <strong>for</strong> <strong>the</strong>se classes in <strong>the</strong> <strong>Caché</strong> Class Reference. For a genericguide to <strong>the</strong> use of <strong>Caché</strong> objects, see <strong>Using</strong> Objects with <strong>Caché</strong> ObjectScript%Library.Persistent MethodsThe following %Library.Persistent proxies are generated:• Id() — Returns <strong>the</strong> persistent object ID, if <strong>the</strong>re is one, of this object. Returns a null string if <strong>the</strong>reis no object ID.string ID = person.Id();<strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong> 35


<strong>Using</strong> <strong>Caché</strong> Proxy Classes• Save() — Stores an in-memory version of an object to disk. If <strong>the</strong> object was stored previously(and thus, already has an OID), Save() updates <strong>the</strong> on-disk version. O<strong>the</strong>rwise, Save() saves <strong>the</strong>object and generates a new OID <strong>for</strong> it.CacheStatus sc = person.Save();• Open() — Loads an object from <strong>the</strong> database into memory and returns an OREF referring to <strong>the</strong>object.• OpenId() — Loads an object from <strong>the</strong> database into memory and returns an OREF referring to<strong>the</strong> object. OpenId() is identical in operation to <strong>the</strong> Open() method except that it uses an ID valueinstead of an OID value to retrieve an instance.Sample.Person person = Sample.Person.OpenId(CacheConnect, "1");• ExistsId() — Checks to see if <strong>the</strong> object identified by <strong>the</strong> specified ID exists in <strong>the</strong> extent.if (!(bool)Sample.Person.ExistsId(CacheConnect, ID)) {string Message = "No person with id " + ID + " in database."; };• DeleteId() — Deletes <strong>the</strong> stored version of <strong>the</strong> object with <strong>the</strong> specified ID from <strong>the</strong> database.CacheStatus sc = Sample.Person.DeleteId(CacheConnect, ID);• Extent() — This is a system provided query that yields a result set containing every instancewithin this extent.CacheCommand Command = Sample.Person.Extent(CacheConnect);• KillExtent() — Deletes all instances of a class and its subclasses.CacheStatus sc = Sample.Person.KillExtent(CacheConnect)%Library.Populate MethodsThe following %Library.Populate proxies are generated:• Populate() — Creates a specified number of instances of a class and stores <strong>the</strong>m in <strong>the</strong> database.long newrecs = (long)Sample.Person.Populate(CacheConnect, 100);• OnPopulate() — For additional control over <strong>the</strong> generated data you can define an OnPopulate()method within your class. If an OnPopulate() method is defined <strong>the</strong>n <strong>the</strong> Populate() method willcall it <strong>for</strong> each object it generates.• PopulateSerial() — Create a single instance of a serial object.For a working example that uses <strong>the</strong> KillExtent() and Populate() methods, see <strong>the</strong>Proxy_6_Repopulate() method in <strong>the</strong> bookdemos sample program (see The <strong>Caché</strong> .<strong>NET</strong> SamplePrograms).36 <strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong>


<strong>Using</strong> Proxy Objects5.3 <strong>Using</strong> Proxy Objects<strong>Caché</strong> proxy objects can be used to per<strong>for</strong>m most of <strong>the</strong> standard operations on instances in a database.This section describes how to open and read an instance, how to create or delete instances, and howto alter and save existing instances.5.3.1 Opening and Reading ObjectsUse <strong>the</strong> OpenId() method to access an instance by ID (instances can also be accessed through SQLqueries, as discussed later in <strong>Using</strong> <strong>Caché</strong> Queries). OpenId() is a static class method, qualified with<strong>the</strong> type name ra<strong>the</strong>r than an instance name:Sample.Person person = Sample.Person.OpenId(CacheConnect, "1");Once <strong>the</strong> object has been instantiated, you can use standard dot notation to read and write <strong>the</strong> personin<strong>for</strong>mation:string Name = person.Namestring ID = person.Id();person.Home.City = "Smallville";person.Home.State = "MN";In this example, person.Home is actually an embedded Sample.Address object. It is automaticallycreated or destroyed along with <strong>the</strong> Sample.Person object.For a working example, see <strong>the</strong> Proxy_1_ReadObject() method in <strong>the</strong> bookdemos sample program(see The <strong>Caché</strong> .<strong>NET</strong> Sample Programs).5.3.2 Creating and Saving Objects<strong>Caché</strong> proxy object constructors use in<strong>for</strong>mation in a CacheConnection object to create a link between<strong>the</strong> proxy object and a corresponding object on <strong>the</strong> <strong>Caché</strong> server:Sample.Person person = new Sample.Person(CacheConnect);person.Name = "Luthor, Lexus A.";person.SSN = "999-45-6789";Use <strong>the</strong> Save() method to create a persistent instance in <strong>the</strong> database. Once <strong>the</strong> instance has been saved,<strong>the</strong> Id() method can be used to get <strong>the</strong> newly generated ID number:CacheStatus sc = person.Save();Display.WriteLine("Save status: " + sc.IsOK.ToString());string ID = person.Id();Display.WriteLine("Saved id: " + person.Id());The ExistsId() class method can be used to test whe<strong>the</strong>r or not an instance exists in <strong>the</strong> database:<strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong> 37


<strong>Using</strong> <strong>Caché</strong> Proxy Classesstring personExists = Sample.Person.ExistsId(CacheConnect, ID).ToString()Display.WriteLine("person " + ID + " exists: " + personExists)For a working example, see <strong>the</strong> Proxy_2_SaveDelete() method in <strong>the</strong> bookdemos sample program(see The <strong>Caché</strong> .<strong>NET</strong> Sample Programs).5.3.3 Closing and Deleting ObjectsThe Close() method disconnects a proxy object from <strong>the</strong> database without destroying it:person.Close();The Dispose() method destroys <strong>the</strong> proxy object:person.Dispose();The methods are identical except that Close() does not destroy <strong>the</strong> object. Nei<strong>the</strong>r method changes <strong>the</strong>persistent instance in <strong>the</strong> database.Important:Always use Close() or Dispose() to close a proxy object.Object reference counts are not maintained on <strong>the</strong> client. Every time <strong>the</strong> server returnsan object (ei<strong>the</strong>r by reference or as a return value) its reference count is increased.When Close() or Dispose() are called, <strong>the</strong> reference count is decreased. The object isclosed on <strong>the</strong> server when <strong>the</strong> count reaches 0.Do not use code such as:person = nothing; //Avoid doing this!This closes <strong>the</strong> proxy object on <strong>the</strong> client side, but does not decrement <strong>the</strong> referencecount on <strong>the</strong> server. This could result in a situation where your code assumes that anobject has been closed, but it remains open on <strong>the</strong> server.The DeleteId() class method deletes <strong>the</strong> instance from <strong>the</strong> database. You can use <strong>the</strong> ExistsId() methodto make sure that it is gone:CacheStatus sc = Sample.Person.DeleteId(CacheConnect, ID);Display.WriteLine("Delete status: " + sc.IsOK.ToString());Display.WriteLine("person " + ID + " exists: "+ Sample.Person.ExistsId(CacheConnect, ID).ToString());For a working example, see <strong>the</strong> Proxy_2_SaveDelete() method in <strong>the</strong> bookdemos sample program(see The <strong>Caché</strong> .<strong>NET</strong> Sample Programs).38 <strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong>


<strong>Using</strong> <strong>Caché</strong> Queries5.4 <strong>Using</strong> <strong>Caché</strong> QueriesA <strong>Caché</strong> Query is an SQL query defined as part of a <strong>Caché</strong> class. For example, <strong>the</strong> Sample.Personclass defines <strong>the</strong> ByName query as follows:Query ByName(name As %String = "") As %SQLQuery(CONTAINID = 1, SELECTMODE ="RUNTIME")[ SqlName = SP_Sample_By_Name, SqlProc ]{SELECT ID, Name, DOB, SSNFROM Sample.PersonWHERE (Name %STARTSWITH :name)ORDER BY Name}In <strong>the</strong> Sample.Person proxy class, ByName is a class method. It accepts a connection object, andreturns an ADO <strong>Provider</strong> CacheCommand object that can be used to execute <strong>the</strong> predefined SQL query:CacheCommand Command = Sample.Person.ByName(CacheConnect);In this example, <strong>the</strong> Command.Connection property has been set to CacheConnect, andCommand.CommandText contains <strong>the</strong> predefined ByName query string. To set <strong>the</strong> Command.Parametersproperty, we create and add a CacheParameter object with a value of A (which will get all recordswhere <strong>the</strong> Name field starts with A):CacheParameter Name_param = new CacheParameter("name", CacheDbType.NVarChar);Name_param.Value = "A";Command.Parameters.Add(Name_param);The CacheParameter and CacheDataReader ADO <strong>Provider</strong> classes must be used to define parametersand execute <strong>the</strong> query, just as <strong>the</strong>y are in an ADO SQL query (see <strong>Using</strong> SQL Queries with CacheParameter).However, this example will use <strong>the</strong> query results to access a set of proxy objects.A CacheDataReader object is used to get <strong>the</strong> ID of each row in <strong>the</strong> result set. Each ID is used toinstantiate <strong>the</strong> corresponding Sample.Person proxy object, which is <strong>the</strong>n used to access <strong>the</strong> data:Sample.Person person;string ID;CacheDataReader reader = Command.ExecuteReader();while (reader.Read()) {ID = reader[reader.GetOrdinal("ID")].ToString();person = Sample.Person.OpenId(CacheConnect, ID);Display.WriteLine(person.Id() + "\t"+ person.Name + "\n\t"+ person.SSN + "\t"+ person.DOB.ToString().Split(' ')[0].ToString());};<strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong> 39


<strong>Using</strong> <strong>Caché</strong> Proxy ClassesFor a working example, see <strong>the</strong> Proxy_3_ByNameQuery() method in <strong>the</strong> bookdemos sample program(see The <strong>Caché</strong> .<strong>NET</strong> Sample Programs).5.5 <strong>Using</strong> Collections<strong>Caché</strong> proxy objects interpret <strong>Caché</strong> collections and streams as standard .<strong>NET</strong> objects. Collectionscan be manipulated by commands such as <strong>for</strong>each, and implement standard methods such as add()and insert().The Person class includes <strong>the</strong> FavoriteColors property, which is a <strong>Caché</strong> list of strings. The <strong>for</strong>eachcommand can be used to access elements of <strong>the</strong> list:CacheListOfStrings colors = person.FavoriteColorsint row = 0;<strong>for</strong>each (string color in colors) {Display.WriteLine(" Element #" + row++ + " = " + color);}The standard collection methods are available. The following example removes <strong>the</strong> first element,inserts a new first element, and adds a new last element:if (colors.Count > 0) colors.RemoveAt(0);colors.Insert(0,"Blue");colors.Add("Green");For a working example, see <strong>the</strong> Proxy_4_Collection() method in <strong>the</strong> bookdemos sample program (seeThe <strong>Caché</strong> .<strong>NET</strong> Sample Programs).5.6 <strong>Using</strong> RelationshipsIf a <strong>Caché</strong> database defines a relationship, <strong>the</strong> <strong>Caché</strong> Proxy Generator will create aCacheRelationshipObject class that encapsulates <strong>the</strong> relationship. The Sample.Company class containsa one-to-many relationship with Sample.Employee (which is a subclass of Sample.Person). The followingexample opens an instance of Sample.Employee, and <strong>the</strong>n uses <strong>the</strong> relationship to generate a list of <strong>the</strong>employee's co-workers.The employee instance is opened by <strong>the</strong> standard OpenId() method. It contains a Company relationship,which is used to instantiate <strong>the</strong> corresponding company object :Sample.Employee employee = Sample.Employee.OpenId(CacheConnect,ID)Sample.Company company = employee.Company;Display.WriteLine("ID: " + (string)employee.Id());Display.WriteLine("Name: " + employee.Name)Display.WriteLine("Works at: " + company.Name);40 <strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong>


The company object contains <strong>the</strong> inverse Employees relationship, which this example instantiates asan object named colleagues. The colleagues object can <strong>the</strong>n be treated as a collection containinga set of Employee objects:CacheRelationshipObject colleagues = company.Employees;Display.WriteLine("Colleagues: ");<strong>for</strong>each (Sample.Employee colleague in colleagues) {Display.WriteLine("\t" + colleague.Name);}<strong>Using</strong> I/O RedirectionFor a working example, see <strong>the</strong> Proxy_5_Relationship() method in <strong>the</strong> bookdemos sample program(see The <strong>Caché</strong> .<strong>NET</strong> Sample Programs).5.7 <strong>Using</strong> I/O RedirectionWhen a <strong>Caché</strong> method calls a Read or Write statement, <strong>the</strong> statement is associated with standard inputor standard output on <strong>the</strong> client machine by default. For example, <strong>the</strong> PrintPerson() method in <strong>the</strong>Sample.Employee class includes <strong>the</strong> following line:Write !,"Name: ", ..Name, ?30, "Title: ", ..TitleThe following example calls PrintPerson() from a Sample.Employee proxy object:Sample.Employee employee = Sample.Employee.OpenId(CacheConnect, "102");employee.PrintPerson();public static OutputRedirection DefaultOutputRedirection =new OutputRedirection(CacheConnection.OutputToConsole);static void OutputToConsole(string output){Console.Out.Write(output);}private void Init() {OutputRedirectionDelegate = DefaultOutputRedirection;InputRedirectionDelegate = DefaultInputRedirection;}In order to provide your own output redirection, you need to implement an output method with <strong>the</strong>same signature as OutputToConsole, create an OutputRedirection object with <strong>the</strong> new method as itsdelegate, and <strong>the</strong>n assign <strong>the</strong> new object to <strong>the</strong> OutputRedirectionDelegate field of a connection object.Example: Redirecting Output to a StreamThis example redirects output to a System.IO.StringWriter stream. First, a new output redirection methodis defined:<strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong> 41


<strong>Using</strong> <strong>Caché</strong> Proxy Classesstatic System.IO.StringWriter WriteOutput;static void RedirectToStream(string output){MyClass.WriteOutput.Write(output);}The new method will redirect output to <strong>the</strong> WriteOutput stream, which can later be accessed by aStringReader. To use <strong>the</strong> new delegate, <strong>the</strong> WriteOutput stream is instantiated, a new connection connis opened, and RedirectToStream() is set as <strong>the</strong> delegate to be used by conn:WriteOutput = new System.IO.StringWriter();conn = new CacheConnection(MyConnectString);conn.Open();conn.OutputRedirectionDelegate =new CacheConnection.OutputRedirection(MyClass.RedirectToStream);When PrintPerson() is called, <strong>the</strong> resulting output is redirected to WriteOutput (which stores it in anunderlying StringBuilder). Now a StringReader can be used to recover <strong>the</strong> stored text:ReadOutput = new System.IO.StringReader(WriteOutput.ToString());string capturedOutput = ReadOutput.ReadToEnd();The redirection delegate <strong>for</strong> <strong>the</strong> connection object can be changed as many times as desired. The followingcode sets conn back to <strong>the</strong> default redirection delegate:conn.OutputRedirectionDelegate = CacheConnection.DefaultOutputRedirection;Input from <strong>Caché</strong> Read statements can be redirected in a similar way, using an InputRedirection delegate.For a working example, see <strong>the</strong> Proxy_7_Redirection() method in <strong>the</strong> bookdemos sample program(see The <strong>Caché</strong> .<strong>NET</strong> Sample Programs).42 <strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong>


6<strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> ClassReferenceThis chapter provides details on <strong>the</strong> classes and methods available with <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong>.The <strong>Provider</strong> assembly (<strong>InterSystems</strong>.Data.CacheClient.dll) contains two primary namespaces:Intersystems.Data.CacheClient and Intersystems.Data.CacheTypes.The CacheClient NamespaceCacheClient is a standard ADO <strong>Managed</strong> <strong>Provider</strong> interface, containing classes that correspond veryclosely to those of o<strong>the</strong>r <strong>Provider</strong>s such as Microsoft's System.Data.OleDb and System.Data.SqlClient.You can use CacheClient versions of standard ADO classes (<strong>for</strong> example, CacheCommand,CacheConnection, CacheDataAdapter, and CacheDataReader) just as you would o<strong>the</strong>r versions of <strong>the</strong>seclasses. <strong>Using</strong> ADO commands that may already be familiar to you, it is possible to access andmanipulate <strong>Caché</strong> databases without having to acquire any special knowledge about <strong>Caché</strong> commandsor syntax.The CacheTypes NamespaceThe CacheTypes namespace contains tools <strong>for</strong> working much more closely with <strong>Caché</strong>. The CacheTypesclasses allow you to create and work with .<strong>NET</strong> objects that are precise analogs of <strong>Caché</strong> objects, andcan be used just as <strong>the</strong>y would be used in native ObjectScript or <strong>Caché</strong> Basic. Unlike <strong>the</strong> loosely coupledADO <strong>Provider</strong> interface, <strong>Caché</strong> proxy objects give you direct control over native <strong>Caché</strong> objects anddata structures.6.1 The CacheClient NamespaceMethods of <strong>the</strong> Intersys.Data.Client namespace provide <strong>the</strong> standard ADO classes and methods.<strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong> 43


<strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> Class Reference6.1.1 Connection and Command Classes• CacheConnection — Represents an open connection to a data source.• CacheCommand — Represents an SQL statement or stored procedure to execute against a datasource.• CacheCommandBuilder — (Scheduled <strong>for</strong> a future release of <strong>Caché</strong>)• CacheParameter — Represents a parameter to a CacheCommand and optionally, its mapping toa System.Data.DataColumn.• CacheParameterCollection — Represents a collection of parameters relevant to a CacheCommandand <strong>the</strong>ir respective mappings to columns in a System.Data.DataSet.• CacheTransaction — Represents an SQL transaction to be made at a data source.- Commit() — Commits <strong>the</strong> database transaction.- Rollback() — Rolls back a transaction from a pending state.6.1.2 Reader and Adapter Classes• CacheDataReader — Provides a way of reading a <strong>for</strong>ward-only stream of data rows from a datasource.• CacheDataAdapter — Represents a set of data commands and a connection to a data source thatare used to fill <strong>the</strong> System.Data.DataSet and update <strong>the</strong> data source.• CacheRowUpdatedEventArgs — Provides data <strong>for</strong> <strong>the</strong> CacheDataAdapter.RowUpdated event.• CacheRowUpdatingEventArgs — Provides data <strong>for</strong> <strong>the</strong> CacheDataAdapter.RowUpdating event.• CacheErrorCollection — Collects all errors generated by CacheDataAdapter.• CacheError — Collects in<strong>for</strong>mation relevant to a warning or error returned by <strong>the</strong> data source.• CacheException (also see CacheTypes.CacheObjException) — The exception that is generatedwhen a warning or error is returned by a data source.6.2 The CacheTypes NamespaceThe <strong>Caché</strong> <strong>Provider</strong>'s <strong>InterSystems</strong>.Data.CacheTypes namespace contains <strong>the</strong> classes and structureslisted below.44 <strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong>


The CacheTypes Namespace• <strong>Caché</strong> Object — Base classes <strong>for</strong> Cache proxy objects.• <strong>Caché</strong> Collection — Classes that implement Cache lists and arrays as standard .<strong>NET</strong> collectionobjects.• Date and Time — Structs that implement Cache date and time classes as standard .<strong>NET</strong> classes.• Exception —• Stream — Classes that implement Cache stream classes as standard .<strong>NET</strong> streams.• SysList —6.2.1 <strong>Caché</strong> Object ClassesThe <strong>Caché</strong> object classes implement <strong>the</strong> mechanisms required to construct <strong>Caché</strong> proxy objects.CacheResourceSrvErrorCacheArgumentCacheStatusCacheObjectCacheCollectionCachePersistentCacheRelationshipObjectCacheSerialObjectCacheMethodSignatureCacheReturnValue• CacheResource —• SrvError —• CacheStatus — Corresponds to <strong>Caché</strong> %Library.Status.• CacheObject — Base class <strong>for</strong> all <strong>Caché</strong> proxy objects.• CacheCollection — Base class <strong>for</strong> <strong>Caché</strong> Collection Classes.• CachePersistent — Base class <strong>for</strong> all persistant <strong>Caché</strong> proxy objects. Corresponds to <strong>Caché</strong>%Library.Persistent.• CacheRelationshipObject — Base class <strong>for</strong> <strong>Caché</strong> relationship proxy objects. Corresponds to <strong>Caché</strong>%Library.RelationshipObject.• CacheSerialObject — Base class <strong>for</strong> all serial <strong>Caché</strong> proxy objects. Corresponds to <strong>Caché</strong>%Library.SerialObject.• CacheMethodSignature — Used by proxy objects to manipulate in<strong>for</strong>mation about arguments andreturn values.CacheArgument ClassesThe classes derived from CacheArgument are used by CacheMethodSignature.<strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong> 45


<strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> Class ReferenceCacheArgumentCacheBinaryArgumentCacheBooleanArgumentCacheCurrencyArgumentCacheDateArgumentCacheDoubleArgumentCacheIntArgumentCacheObjArgumentCacheStatusArgumentCacheStringArgumentCacheSysListArgumentCacheTimeArgumentCacheTimestampArgumentCacheReturnValue ClassesThe classes derived from CacheReturnValue are used by CacheMethodSignature.CacheReturnValueCacheBinaryReturnValueCacheBooleanReturnValueCacheCurrencyReturnValueCacheDateReturnValueCacheDoubleReturnValueCacheIntReturnValueCacheObjReturnValueCacheStatusReturnValueCacheStringReturnValueCacheSysListReturnValueCacheTimeReturnValueCacheTimestampReturnValue6.2.2 <strong>Caché</strong> Collection ClassesThese classes correspond to <strong>the</strong> <strong>Caché</strong> classes derived from %Library.CacheCollection. <strong>Caché</strong> collectionclasses are interpreted as standard .<strong>NET</strong> collections. They can be manipulated with commands suchas <strong>for</strong>each, and implement standard methods such as add() and insert().CacheObjectCacheCollectionCacheArrayOfObjectsCacheListOfObjectsCacheArrayOfDT< T >CacheListOfDT< T >• CacheCollection — Abstract base class <strong>for</strong> collections.• CacheArrayOfObjects — Corresponds to <strong>Caché</strong> %Library.ArrayOfObjects.• CacheListOfObjects — Corresponds to <strong>Caché</strong> %Library.ListOfObjects.• CacheArrayOfDT< T > — Abstract base class <strong>for</strong> arrays of data types (see below <strong>for</strong> derivedclasses).• CacheListOfDT< T > — Abstract base class <strong>for</strong> lists of data types (see below <strong>for</strong> derived classes).46 <strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong>


CacheArray ClassesThe classes derived from CacheArrayOfDT< T > correspond to <strong>Caché</strong> %Library.ArrayOfDataTypes.CacheArrayOfDT< T >CacheArrayOfBinariesCacheArrayOfBooleansCacheArrayOfCurrencyCacheArrayOfDatesCacheArrayOfDateTimesCacheArrayOfDoublesCacheArrayOfIntegersCacheArrayOfStatusesCacheArrayOfStringsCacheArrayOfSysListsCacheArrayOfTimesCacheList ClassesThe classes derived from CacheListOfDT< T > correspond to <strong>Caché</strong> %Library.ListOfDataTypes.CacheListOfDT< T >CacheListOfBinariesCacheListOfBooleansCacheListOfCurrencyCacheListOfDatesCacheListOfDateTimesCacheListOfDoublesCacheListOfIntegersCacheListOfStatusesCacheListOfStringsCacheListOfSysListsCacheListOfTimesThe CacheTypes Namespace6.2.3 Date and Time Structs<strong>Caché</strong> date and time data types.• CacheDate — Corresponds to <strong>Caché</strong> %Library.Date.• CacheDateTime — Corresponds to <strong>Caché</strong> %Library.TimeStamp.• CacheTime — Corresponds to <strong>Caché</strong> %Library.Time.6.2.4 Exception Classes(CacheClient.CacheException)CacheObjExceptionCacheInternalExceptionCacheUserErrorExceptionCacheDisconnectedObjectExceptionCacheInvalidCollectionElementtExceptionCacheInvalidCollectionKeyException<strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong> 47


<strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> Class Reference6.2.5 Stream ClassesCache stream classes are interpreted as standard .<strong>NET</strong> streams.CacheStreamCacheBinaryStreamCacheFileBinaryStreamCacheCharacterStreamCacheFileCharacterStream• CacheStream — Abstract base class <strong>for</strong> streams.• CacheBinaryStream — Corresponds to <strong>Caché</strong> abstract class %Library.BinaryStream.• CacheFileBinaryStream — Corresponds to <strong>Caché</strong> %Library.FileBinaryStream.• CacheCharacterStream — Corresponds to <strong>Caché</strong> abstract class %Library.CharacterStream.• CacheFileCharacterStream — Corresponds to <strong>Caché</strong> %Library.FileCharacterStream.6.2.6 SysList ClassesCacheSysListCacheSysListReader48 <strong>Using</strong> <strong>the</strong> <strong>Caché</strong> <strong>Managed</strong> <strong>Provider</strong> <strong>for</strong> .<strong>NET</strong>

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!