This project is read-only.

NDatabase Basic Sample


  • The purpose of this sample is to show how to work with NDatabase as the storage solution in the simple case.
  • After that you could successfully store your objects into NDatabase and then work with them whenever you want.

Preparing domain objects for our sample


We need some object structure for presenting work on NDatabase. Our data model will define warriors which could hold two items. Items could be field or sword.

Items

In our data model we have two kinds of items: armor and weapon. Both contain attributes: attack and defense which will modify warrior attributes.

The base interface for all items defines two attributes:

public interface IItem
{
    int Attack { get; }
    int Defense { get; }
}
Then we have two interfaces describing the type of the item:

public interface IArmor : IItem
{
}

public interface IWeapon : IItem
{
}
Implementations of above interfaces:

public sealed class Field : IArmor
{
    private readonly int _defense;

    public Field(int value)
    {
        _defense = value;
    }

    #region IArmor Members

    public int Defense
    {
        get { return _defense; }
    }

    public int Attack
    {
        get { return 0; }
    }

    #endregion

    public override string ToString()
    {
        return string.Format("Field +{0}D", Defense);
    }
}

public sealed class Sword : IWeapon
{
    private readonly int _attack;

    public Sword(int value)
    {
        _attack = value;
    }

    #region IWeapon Members

    public int Attack
    {
        get { return _attack; }
    }

    public int Defense
    {
        get { return 0; }
    }

    #endregion

    public override string ToString()
    {
        return string.Format("Sword +{0}A", Attack);
    }
}
The initial state of warrior doesn't contain the items. So we need to mark that there is no item there. To do that we are using class NoItem:

public sealed class NoItem : IItem
{
    public static readonly IItem Instance = new NoItem();

    private NoItem()
    {
    }

    #region IItem Members

    public int Attack
    {
        get { return 0; }
    }

    public int Defense
    {
        get { return 0; }
    }

    #endregion

    public override string ToString()
    {
        return "NoItem";
    }
}

Warrior

Warrior is defined by IHero interface:

public interface IHero
{
    IItem RightHand { set; }
    IItem LeftHand { set; }

    int Attack { get; }
    int Defense { get; }

    int Level { get; }
    string Name { get; }
}
This interface contains two items. One is hold in left hand and the second in the right hand. Additionally, hero is described by his level, name and two attributes: attack and defense. Attack and defense attributes are modified by items which hero has assigned.

The implementation of IHero interface:

public sealed class Warrior : IHero
{
    private readonly string _name;
    private int _attack;
    private int _defense;

    public Warrior(string name)
    {
        if (string.IsNullOrEmpty(name))
            throw new ArgumentNullException("name",
                                    "Name of warrior cannot be empty.");

        _name = name;
        RightHand = NoItem.Instance;
        LeftHand = NoItem.Instance;

        Attack = 3;
        Defense = 3;
    }

    #region IHero Members

    public IItem RightHand { private get; set; }
    public IItem LeftHand { private get; set; }

    public int Attack
    {
        get { return _attack + RightHand.Attack + LeftHand.Attack; }
        private set { _attack = value; }
    }

    public int Defense
    {
        get { return _defense + RightHand.Defense + LeftHand.Defense; }
        private set { _defense = value; }
    }

    public int Level
    {
        get { return 1; }
    }

    public string Name
    {
        get { return _name; }
    }

    #endregion

    public override string ToString()
    {
        return string.Format("[{0}]: RH: {1}, LH: {2}, Att: {3}, Def: {4}, Lvl: {5}",
                             Name, RightHand, LeftHand, Attack, Defense, Level);
    }
}

Storing objects


Firstly, we create the two warrior objects with a different names.

var warrior1 = new Warrior("Warrior 1");
var warrior2 = new Warrior("Warrior 2");
To store the objects we need to open our database with parameter as the name of our db file. Our db file name is defined by constant string:

private const string DBName = "game.ndb";
Now we could open our database and store prepared two objects.

using (var odb2 = OdbFactory.Open(DBName))
{
    odb2.Store(warrior1);
    odb2.Store(warrior2);
}

Updating them


Now, is the time for preparing our equipment which could be used by our powerful warriors.

var sword1 = new Sword(5);
var sword2 = new Sword(3);

var field1 = new Field(3);
var field2 = new Field(5);
Okay. Now we could open our database and retrieve already stored objects. Then we could use prepared items to update warriors, and then store them back into database.

For the case when you are opening database with the same name as for the first time, you can use OdbFactory.OpenLast() method to do that easier.

using (var odb = OdbFactory.OpenLast())
{
    IList<Warrior> warriors = odb.Query<Warrior>().Execute<Warrior>().ToList();

    warriors[0].RightHand = sword1;
    warriors[0].LeftHand = field1;

    warriors[1].RightHand = sword2;
    warriors[1].LeftHand = field2;

    odb.Store(warriors[0]);
    odb.Store(warriors[1]);
}
Now our database contains updated warriors, and we could perform some action on them.

Querying and displaying items from database



Now we could display items which are in the database. To do that we are opening db, then we are querying for items and finally, we are displaying the retrieved items.

using (var odb1 = OdbFactory.OpenLast())
{
    var query = new CriteriaQuery<IItem>();

    IList<IItem> items = odb1.Query<IItem>(query).Execute<IItem>().ToList();

    foreach (var item in items)
        Console.WriteLine(item);
}
The output for that is:

NoItem
Sword +5A
Sword +3A
Field +3D
Field +5D
Finally, we are querying for warriors and displaying them in the same way as for items. After that, we will remove both objects from db.

using (var odb1 = OdbFactory.OpenLast())
{
    IList<Warrior> warriors = odb1.Query<Warrior>().Execute<Warrior>().ToList();

    foreach (var warrior in warriors)
        Console.WriteLine(warrior);

    Console.WriteLine("Remove warriors");

    odb1.Delete(warriors[0]);
    odb1.Delete(warriors[1]);
}
The output for that is:

[Warrior 1]: RH: Sword +5A, LH: Field +3D, Att: 8, Def: 6, Lvl: 1
[Warrior 2]: RH: Sword +3A, LH: Field +5D, Att: 6, Def: 8, Lvl: 1
Now are database should have no warrior objects. To check that we will query for warriors again, and we will check the count of returned items.

int count;
using (var odb = OdbFactory.OpenLast())
    count = odb.Query<Warrior>().Execute<Warrior>().Count;

Console.WriteLine("Warriors count: {0}", count);
And the final output is:

Warriors count: 0

Last edited Dec 29, 2012 at 9:36 AM by jacek, version 15

Comments

No comments yet.