NoSQL with MongoDB, NoRM and ASP.NET MVC - Part 2
- by shiju
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 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();
}
}
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 can managing object graph of domain entities are pretty cool. Download the Source - You can download the source code form http://mongomvc.codeplex.com