Sunday, November 14, 2010

MVC 2.0 with DB4O

Object-Oriented Databases

The aim of this blog is to firstly give an introduction of what an object-oriented database is, showing how to install DB4O, any shortcomings and finally to give an example in a C# .NET 4 MVC 2 shopping cart project.

What is an Object-Oriented Database?

An object-oriented database is a database model (OODBMS), unlike relational database management systems which hold data in relational rows and columns the OODBMS holds information as objects in the same way as object-oriented programming.

OODBMS is useful when used with object-oriented programming as no translation needs to take place between objects in code and objects in a database, the same objects can be referenced in each.

Why choose OODBMS over RDBMS?

OODBMS are faster than RDBMS and can be programmed without making changes to the full system.

As navigation with OODBMS is done with pointers data access is done very efficiently.

On the negative, OODBMS are optimised for specific search routes and will tend to be slower for general-purpose queries than relational however direct object references may be maintained to allow for both types of access.

So what OODBMS should I choose?

This depends on the language you are programming in, I’m pro open source and the language I am writing for this example is in .Net I have selected the highly rated db4o: http://www.db4o.com/about/productinformation/db4o/

This o-o database has libraries for both Java and .NET, for a full list and comparison of OODBMS see this wiki link: http://en.wikipedia.org/wiki/Comparison_of_object_database_management_systems

Installation guide of db4o for .NET

Download the production release from the following location: http://developer.db4o.com/Downloads.aspx

The following steps are for db4o-7.12-net35.msi

Setup type: Typical
Accept the default installation location
Go though the defaults and click Finish to complete the installation

If you have more than one version of Visual Studio installed you get the choice of plugin to install.

‘To proceed with the installation of the Object Manager Enterprise plugin for VS please choose the appropriate shortcut from your db4objects Start menu’

The plugin does not work with Microsoft Visual Web Developer – you will need the fully blown version of the Visual Studio.

The tutorial automatically loads on completion of installation from here code examples can be obtained for processes such as opening databases to CRUD to LINQ and SODA queries.

The only DLL you need to build against is C:\Program Files\db4o\db4o-7.12\bin\net-3.5\ Db4objects.Db4o.dll.

Issues
Cache
Db40 has its own caching, the default is ‘CachingStorage’, db4o uses a LRU/Q2 caching strategy. http://developer.db4o.com/Documentation/Reference/db4o-8.0/net35/reference/index_Left.html#CSHID=configuration%2Ffile%2Fstorage%2Fisolated_storage.htmStartTopic=Content%2Fconfiguration%2Ffile%2Fstorage%2Fisolated_storage.htmSkinName=RedVersant

Load balancing
http://developer.db4o.com/Documentation/Reference/db4o-8.0/net35/reference/index_Left.html#CSHID=configuration%2Ffile%2Fstorage%2Fisolated_storage.htmStartTopic=Content%2Fconfiguration%2Ffile%2Fstorage%2Fisolated_storage.htmSkinName=RedVersant

Locking
http://www.gamlor.info/wordpress/?p=779

Serialized objects
As soon as objects are serialized the object-identity is lost, this is typical in web-scenarios or web-services, there are a number of different ids, one of which is “ID-Field On Classes With a ID-Generator”.

The project

I developed this MVC 2.0 project using Visual Studio 2010 Ultimate.

The source is available on GitHub.

It is assumed you have working knowledge of the MVC framework.

The only DLLs I referenced from my application are:

Db4objects.Db4o
Db4objects.Db4o.Linq

The second was included as I used Linq queries on the object database.

To keep this example simple I have not addressed the issues of load balancing and isolated storage.

I have created a new class in the Models folder: StoreDB4O

In the class I define the yap file – this is the file DB4O uses to store the database.


   1:  readonly static string StoreYapFileName = Path.Combine( 
   2:    Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), 
   3:    "store.yap"); 

...and obtain it using the following method:

   1:  private static IObjectContainer GetDB()
   2:  {
   3:    returnDb4oEmbedded.OpenFile(Db4oEmbedded.NewConfiguration(), StoreYapFileName);
   4:  }



In order to get test data in to the project I have created a method called LoadTestData(), this is called from Application_Start() in Global.asax and removes the content of the database:


   1:  File.Delete(StoreYapFileName);


And stores the sample data in Category and Product objects:


   1:  IObjectContainer db = GetDB();
   2:  try
   3:  {
   4:      Category category = new Category { CategoryId = 1, Name = "Bikes" };
   5:      StoreCategory(db, category);




   1:  private static void StoreCategory(IObjectContainer db, Category category)
   2:  {
   3:      db.Store(category);
   4:  }

There is nothing special about the objects that are stored in the database.

   1:  namespace MvcDB4O.Models
   2:  {
   3:      public class Category
   4:      {
   5:          public int CategoryId { get; set; }
   6:          public string Name { get; set; }
   7:      }
   8:  }

In addition to storing data in object I have implemented methods that return data using Linq queries as example of which returns a list of products by category name:

   1:  public static IEnumerable<Product> GetProductsByCategoryName(string name)
   2:          {
   3:              IObjectContainer db = GetDB();
   4:   
   5:              try
   6:              {
   7:                  return new List<Product>(from Product p in db
   8:                                            where p.Category.Name == name
   9:                                            orderby p.Name
  10:                                            select p).Distinct(new ProductByNameEquality());
  11:   
  12:              }
  13:              finally
  14:              {
  15:                  db.Close();
  16:              }
  17:          }

One important thing to mention is to always return a copy of the object from the database otherwise the connection of the database will be required to be open when accessing data from the objects.

Another gotcha is that when updating existing data, the same object will be required from the database within the same session i.e. In this example, the basket has the count decremented and the basket is then placed back in the object database, if this was done in two separate sessions with the database a second basket will be added to the database and the existing one will also exist.


   1:  public static IEnumerable<Product> GetProductsByCategoryName(string name)
   2:          {
   3:              IObjectContainer db = GetDB();
   4:   
   5:              try
   6:              {
   7:                  return new List<Product>(from Product p in db
   8:                                            where p.Category.Name == name
   9:                                            orderby p.Name
  10:                                            select p).Distinct(new ProductByNameEquality());
  11:   
  12:              }
  13:              finally
  14:              {
  15:                  db.Close();
  16:              }
  17:          }

The MVC structure here is nothing new, the Home\Index.aspx shows the categories and a link to the StoreController Browse method:


   1:          <% foreach (MvcDB4O.Models.Category category in Model.Categories)
   2:             { %>         
   3:          <li>
   4:              <%: Html.ActionLink(category.Name, "Browse", "Store", new { category = category.Name }, null)%>
   5:          </li>     
   6:          <% } %>
   7:   
   8:          public ActionResult Browse(string category)
   9:          {
  10:              // Retrieve Category and Products from database     
  11:              var storeBrowseViewModel = new StoreBrowseViewModel()
  12:                  { 
  13:                      Category = StoreDB4O.GetCategory(category),
  14:                      Products = StoreDB4O.GetProductsByCategoryName(category)
  15:                  };
  16:              return View(storeBrowseViewModel);
  17:          }

The View Model is populated and used in the Store\Browse.aspx page.

   1:      public class StoreBrowseViewModel
   2:      {
   3:          public Category Category { get; set; }
   4:          public IEnumerable<Product> Products { get; set; }
   5:      }
   6:   
   7:          <% foreach (MvcDB4O.Models.Product product in Model.Products)
   8:             { %>         
   9:          <li>
  10:              <%: Html.ActionLink(product.Name, "Details", "Store", new { id = product.ProductId }, null)%>
  11:          </li>     
  12:          <% } %>


I hope this has served to show how to connect to an object database in particular DB4O using MVC.

Please ask any questions you may have and I welcome your comments.







Tuesday, October 19, 2010

How to download, install, configure and upload content to GitHub

Introduction

This post describes how to download, install, configure and upload content to GitHub.

What is GitHub?

Git is a distributed version control system. GitHub provides a way for sharing content in Git with other people

How do I get GitHub?

Sign up for a free account here: https://github.com/signup/free

Once you have your account, create a new repository: http://github.com/repositories/new

After setting up your account you will need to Download and Install Git on your PC.

msysgit is the Windows version, available here: http://code.google.com/p/msysgit/downloads/list?can=3

At the time of writing the latest version is: 1.7.3.1

Accept the defaults when installing

So how do I set it up?

Once Git is installed, run the application Git > Git GUI > Create New Repository > [enter a name] > Create

This will create a new folder in your Documents and Settings folder with the name of your repository

Copy or create your new project in the folder.

In Explorer, right click on the new top level folder > Git add all files now

Run the command prompt: Git > Git Bash

git config --global user.name "Your Name"
git config --global user.email "Your email address"


Next set up a SSH public key on your PC that links you to the repository:

http://help.github.com/msysgit-key-setup/

Change to the location of the new repository:
cd MvcDB4O

git init
ssh-keygen –t rsc –C "Your email address"

You will be prompted for a location for the key, hit enter for the default
Enter a passphrase

You will be told the location of the ssh public key

Create an SSH public key from the website: https://github.com/account > add another public key

Give it a title and the key you created in Git Bash

So how do I push my files to GitHub?

In Git Bash
Change to the directory of the repository

git remote add origin git@github.com:your-git-username/repository-name.git

git push origin master (you will be asked for your passphrase)


(ensure the .ssh folder exists in the repository you are uploading)

Switch to GitHub to view the uploaded files

Conclusion

Hopefully you have found this information useful - good luck with your Git friends.

Friday, July 30, 2010

Welcome

Hello,

I hold the post of Project Technical Lead at Wiggle Limited.

I will be posting my thoughts, ideas and comments on technical and managerial solutions I come across on a day to day basis.

Please feel free to make any comments to my posts and I will get back to you as soon as possible.

Check out my linkedin and twitter accounts or contact me via email.