NoSQL with MongoDB, NoRM and ASP.NET MVC - Part 2

 
In my last post, I have given an introduction to MongoDB and NoRM using an ASP.NET MVC demo app. I have updated the demo ASP.NET MVC app and a created a new drop at codeplex. You can download the demo at http://mongomvc.codeplex.com/

In my last post, we have discussed to doing basic CRUD operations against a simple domain entity. In this post, let’s discuss on domain entity with deep object graph.

The below is our domain entities

 

public class Category

{

 

    [MongoIdentifier]

    public ObjectId Id { get; set; }

 

    [Required(ErrorMessage = "Name Required")]

    [StringLength(25, ErrorMessage = "Must be less than 25 characters")]

    public string Name { get; set;}

    public string Description { get; set; }

    public List<Expense> Expenses { get; set; }

 

    public Category()

    {

        Expenses = new List<Expense>();

    }

}

 

 

public class Expense

{

    [MongoIdentifier]

    public ObjectId Id { get; set; }

    public Category Category { get; set; }

    public string  Transaction { get; set; }

    public DateTime Date { get; set; }

    public double Amount { get; set; }

 

}

 

 We have two domain entities - Category and Expense. A single category contains a list of expense transactions and every expense transaction should have a Category.

 

The MongoSession class

 

internal class MongoSession : IDisposable

{

    private readonly MongoQueryProvider provider;

 

    public MongoSession()

    {

        this.provider = new MongoQueryProvider("Expense");

    }

 

    public IQueryable<Category> Categories

    {

        get { return new MongoQuery<Category>(this.provider); }

    }

    public IQueryable<Expense> Expenses

    {

        get { return new MongoQuery<Expense>(this.provider); }

    }

    public MongoQueryProvider Provider

    {

        get { return this.provider; }

    }

 

    public void Add<T>(T item) where T : class, new()

    {

        this.provider.DB.GetCollection<T>().Insert(item);

    }

 

    public void Dispose()

    {

        this.provider.Server.Dispose();

    }

    public void Delete<T>(T item) where T : class, new()

    {

        this.provider.DB.GetCollection<T>().Delete(item);

    }

 

    public void Drop<T>()

    {

        this.provider.DB.DropCollection(typeof(T).Name);

    }

 

    public void Save<T>(T item) where T : class,new()

    {

        this.provider.DB.GetCollection<T>().Save(item);           

    }

 

 

}   

 

ASP.NET MVC view model  for Expense transaction

 

public class ExpenseViewModel

{

    public ObjectId Id { get; set; }

 

    public ObjectId CategoryId { get; set; }

 

    [Required(ErrorMessage = "Transaction Required")]       

    public string Transaction { get; set; }

 

    [Required(ErrorMessage = "Date Required")]       

    public DateTime Date { get; set; }

 

    [Required(ErrorMessage = "Amount Required")]   

    public double Amount { get; set; }

 

    public IEnumerable<SelectListItem> Category { get; set; }

}

 

Let's create an action method for Insert and Update a expense transaction

 

[HttpPost]

public ActionResult Save(ExpenseViewModel expenseViewModel)

{

    try

    {

        if (!ModelState.IsValid)

        {

            using (var session = new MongoSession())

            {

                var categories = session.Categories.AsEnumerable<Category>();

                expenseViewModel.Category = categories.ToSelectListItems(expenseViewModel.CategoryId);   

            }

            return View("Save", expenseViewModel);

        }

 

        var expense=new Expense();

        ModelCopier.CopyModel(expenseViewModel, expense);

 

        using (var session = new MongoSession())

        {

            ObjectId Id = expenseViewModel.CategoryId;

            var category = session.Categories

                .Where(c => c.Id ==Id  )

                .FirstOrDefault();

            expense.Category = category;

            session.Save(expense);

        }

        return RedirectToAction("Index");

    }

    catch

    {

        return View();

    }

}

 

To save a expense transaction is very easy. You just need to create a Expense object and set the Category object for Category property. The session.Save method will do the all magic for you. If it is a new Expense traction, it will create a new record to MongoDB with associated Category object and update the Expense if it is existing Expense record.

 

Query with Expenses

using (var session = new MongoSession())

{

    var expenses = session.Expenses.

        Where(exp => exp.Date >= StartDate && exp.Date <= EndDate)

        .AsEnumerable<Expense>();

}

 

We are doing a LINQ query expression with a Date filter. We can easily work with MongoDB using NoRM driver and managing object graph of domain entities are pretty easy.


 Download the Source - You can download the source code from http://mongomvc.codeplex.com

2 Comments

  • cool article, but one thing , when update Category entity, the category of the same id in expense collection don't change, any deeper step to take for this, am 'i wrong?

  • I downloaded the sample and I get an error pertaining to the creation of the database, which has a location defined of mongodb://localhost/Expense. Am I supposed to create a virtual directory that points to C:\data\db ?

    I am missing something....

Comments have been disabled for this content.