In this example we’ll create our first persistent object. To compile this example you should:

  • create an empty C# project
  • add a file with the following source code
  • add a reference to DataObjects.Net assembly (DataObjects.NET.dll) to the project

Most of difficult-to-understand places are commented (comments are located directly in the source code).

Sample output

DataObjects.Net: FirstStep demo

Select database server to use:
1) Microsoft SQL Server
2) Oracle
3) Native Oracle
4) SAP DB
> 1
Selected: Microsoft SQL Server.
Reading product key...

Building domain...
Age: 2
Creating savepoint...
Savepoint created.
Age: 3
Rolling back to the savepoint...
Rollback completed.
Age: 2

Press Enter to close...

Source code (FirstStep.cs)

using System;
using System.IO;
using System.Globalization;
using DataObjects.NET;
using DataObjects.NET.Attributes;

namespace Demo_FirstStep
{
  // This is our first persistent class.
  // Don't worry about abstract modifiers - DataObjects.Net
  // will automatically create a descendant of this class
  // called "proxy" class that will implement the abstract 
  // member. 
  // This class will be created transparently for you in 
  // the runtime (to be exact - during the execution of the
  // Domain.Build(...) method).
  public abstract class Animal: DataObject {
    // A single persistent property
    public abstract int Age {get; set;}
  }

  class FirstStep
  {
    [STAThread]
    static void Main(string[] args)
    {
      Console.WriteLine("DataObjects.Net: FirstStep demo\n");

      string connectionUrl = "";
      while (connectionUrl=="") {
        Console.Write("Select database server to use:\n" +
                      "1) Microsoft SQL Server\n" +
                      "2) Oracle\n" +
                      "3) Native Oracle\n" +
                      "4) SAP DB\n" +
                      "> ");
        string dbType = Console.ReadLine();
        switch (dbType) {
          case "1":
            Console.WriteLine("Selected: Microsoft SQL Server.");
            connectionUrl = "mssql://localhost/DataObjectsDotNetDemos";
            break;
          case "2":
            Console.WriteLine("Selected: Oracle.");
            connectionUrl = "oracle://admin:admin@localhost/Demos";
            break;
          case "3":
            Console.WriteLine("Selected: Native Oracle.");
            connectionUrl = "nativeoracle://admin:admin@localhost/Demos";
            break;
          case "4":
            Console.WriteLine("Selected: SAP DB.");
            connectionUrl = "sapdb://admin:admin@localhost/Demos";
            break;
          default:
            Console.WriteLine("Illegal selection.");
            break;
        }
      }

      // First we should create Domain instance.
      // To create it we need a product key (for Express version
      // any key is acceptable)
      Console.WriteLine("Reading product key...");
      // In a normal case you SHOULD specify your product 
      // key during the call of Domain constructor, but
      // in all samples we read this key from file - this
      // allows to skip recompliation for a particular product 
      // key.
      // Before running this (or any other) sample you should
      // create file "ProductKey.txt" containing single line 
      // with your product key and put this file to DataObjects.Net
      // installation folder.
      string productKeyFile = @"..\..\..\..\ProductKey.txt"; 
      string productKey = "";
      if (File.Exists(productKeyFile))
        using (StreamReader sr = new StreamReader(productKeyFile)) {
          productKey = sr.ReadToEnd().Trim();
        }

      Console.WriteLine("");
      // OK, let's create Domain instance now:  
      Console.WriteLine("Building domain...");
      // Format of connection URL: 
      //   protocol://user:password@server\instance/database?p1=v1&p2=v@[&..]
      Domain domain = new Domain(connectionUrl, productKey);
      // At least one culture should be registered
      domain.RegisterCulture(
        new Culture("En","U.S. English", new CultureInfo("en-us",false)));
      // It's always necessary to specify default culture
      domain.Cultures["En"].Default = true; 
      // Here we register all types from "Demo_FirstStep" namespace
      domain.RegisterTypes("Demo_FirstStep");
      // This part allows output of the debug info and proxy assembly
      // debugging (e.g. step into it) in the Debug configuration
      #if DEBUG
        domain.DebugInfoOutputFolder = @"C:\Debug";
      #endif
      // Now we can build the domain. An exclusive access
      // to domain database should be provided for this period.
      domain.Build(DomainUpdateMode.Recreate);

      // Now domain is operable. From this point domain can be shared
      // (used concurrently) between multiple threads.
      
      // Simply a variable
      long instanceID = 0;
      
      // You should work with Session by the same way :)
      using (Session session = new Session(domain)) {
        // We can access the storage only during transaction, so...
        session.BeginTransaction();

        // That's how we create our first persistent instance
        Animal a = (Animal)session.CreateObject(typeof(Animal));
        // Instance is already persisted to the storage now
        // Let's set the first persistent property
        a.Age = 2;
        // And read the instance ID
        instanceID = a.ID;

        // And finally commit our work
        session.Commit();
      }
      
      // Let's create another Session
      using (Session session = new Session(domain)) {
        session.BeginTransaction();

        // Ans fetch the instance by its ID
        Animal a = (Animal)session[instanceID];
        Console.WriteLine("Age: {0}", a.Age); // Output: 2
        
        // Let's try Savepoints
        Console.WriteLine("Creating savepoint...");
        Savepoint sp = new Savepoint(session);
        Console.WriteLine("Savepoint created.");
        a.Age = 3;
        Console.WriteLine("Age: {0}", a.Age); // Output: 3
        Console.WriteLine("Rolling back to the savepoint...");
        sp.Rollback();
        Console.WriteLine("Rollback completed.");
        // During execution of the next line DataObjects.Net will
        // notice that transactional context is changed (by
        // rollback to the savepoint operation) and instance
        // will be reloaded.
        Console.WriteLine("Age: {0}", a.Age); // Output: 2

        // Heh :) But what ?
        session.Commit();
      }

      Console.Write("\nPress Enter to close... ");
      Console.ReadLine();
    }
  }
}