# C# Schema Definition

> C# applications define the database classes to be managed in the eXtremeDB runtime using native C# class syntax applying special attributes.

> For example, the following code snippet would define a database with two classes Department and Employee:

>         [Persistent]
>         class Department
>         {
>             [Indexable(Type = Database.IndexType.BTree, Unique = true)]
>             public String code;
>             public String name;
>             [Indexable(Type = Database.IndexType.Hashtable, Unique = true)]
>             public int dept_no;
>         }

>         [Index("byDept_EmployeeName", Keys = new string[] { "dept_no", "name" }, Unique = false)]

>         [Persistent]
>         class Employee
>         {
>             [Indexable(Type = Database.IndexType.BTree, Unique = true)]
>             public String  name;
>             public int  dept_no;
>         }

> Note that the attributes `[Persistent]`, `[Indexable()]`and `[Index()]` are used to specify the classes and indexes to be generated and maintained in the database.

> ## eXtremeDB C# Database Attributes

> The attributes that are recognized as eXtremeDB database specifications are as follows:

> Persistent

> Class attribute: Marks this class as “stored in the database” and optionally provides some attributes of this class;

> - `Persistent(autoid=true)` - Creates an `autoid` index
> - `Persistent(list=true)` - Creates a list index
> - `Persistent(large=true)` - Declares the standard storage model (default)
> - `Persistent(compact=true)` - Declares the compact storage model
> - `Persistent(inmemory=true)` - Declares this class as in-memory (default)
> - `Persistent(disk=true)` - Declares this class as disk-based (i.e on persistent storage media)
> - `Persistent(local=true)` - Declares this class as `local` for eXtremeDB High Availability partial replication

> Index

> Class attribute: Defines a compound (multi-field) index; possible properties are:

> name="indexName"
> Identifies this index
> keys={Key(“field1”) [, Key(“field2”) …] }
> List of key fields
> unique=true
> Creates a b-tree index (the default), true enforces uniqueness; if `false` allows duplicates
> thick=true
> Optimized for a large number of duplicates
> descending=true
> Indexes are `ascending` by default
> initSize=N
> For hash indexes; `N` is the initial size of the hash table
> type=Database.IndexType.BTree

> Possible `Database.IndexType` values are:

> - BTree - Creates a `tree` index (the default)
> - Hashtable - Creates a `hash` index
> - Patricia - Creates a `patricia` index
> - RTree - Creates an `rtree` index
> - RTreeOfPoint - Creates an `rtree` index
> - KDTree - Creates a `kdtree` index
> - Trigram - Creates a `trigram` index

> for example:

>         [Index(name="byName", keys={ Key("lastName"), Key("firstName") }, unique=true )]

>         class Employee
>         {
>             String  firstName;
>             String  lastName;
>             Address address;
>             long    salary;
>         }

> Indexable

> Field attribute: Specifies an index on the following field. The index will have the same name as the field. With the exception of `name` and `keys` properties, the possible properties are the same as for class attribute `Index` (above).

> for example

>         class Obj
>         {
>             [Indexable(Type=Database.IndexType.BTree, Unique=true)]
>             public int value;
>         }

> Encoding

> Field attribute: Specifies the encoding of string fields. Can be any valid encoding supported by the C# runtime. `UTF-8` is the default. Examples:

>         [Encoding("UTF-16")]
>         String s1;
>         [Encoding("ASCII")]
>         String s2;

> Blob

> Field attribute: Uses eXtremeDB BLOB type for storing a byte array; for example:

>         [Blob] public byte[] photo;

> Dimension

> Field attribute: Specifies the dimension for fixed size arrays (char, scalar) An array without a dimension will be treated as a `vector` (dynamic array). Example:

>         [Dimension(8)]

>         String prefix;

> Numeric

> Field attribute: Specifies the width and precision for decimal fields. Example:

>         [Numeric(12,3)]

>         decimal d;
>     // Equivalent to decimal<12,3> d;

> Binary

> Field attribute: Specifies a fixed length Binary field. Example:

>         [Binary(100)]

>         byte[] dim100_binary;
>     // A Binary array of 100 bytes

> Varbinary

> Field attribute: Specifies a variable length Binary field. Example:

>         [Varbinary]

>         byte[] var_binary;
>     // A Binary vector (dynamic array)

> Nullable

> Field attribute: Specifies that this field can be null. The C# "?" syntax will also produce a nullable database field. Example:

>         [Nullable]

>         bool isALive; // Explicitly declared nullable field
>         bool? isDead; // Imnplicitly declared nullable field

> Optional

> Field attribute: Defines a structure field as optional; for example:

>         [Optional]
>         NestedStruct opt_nested;

> References

> Field attribute: Used to declare a field of type `ref` which refers to a Class in the schema; for example:

>         [References(ClassA)]
>         ulong a;

> ## SQL column names and C# fields

> When using SQL tables associated with C# classes, be aware that the SQL column names are case sensitive. The SQL table column names will correspond to the exact upper and lower case names used in the C# persistent classes.