MemoDb 0.1.0 alpha released!

February 11, 2011 Leave a comment

The first release of MemoDb is out!
It supports:

  • Inserts
  • Updates
  • Delete
  • Insert references and collections by cascade
  • Delete collection children by cascade (aka cascade-all-delete-orphans)
  • EntityRef references
  • Id auto generation (With defaults for ints, long and guid)

You can download it from here.

To see other posts of MemoDb:

Advertisements

MemoDb: Cascades and Collections support

February 10, 2011 Leave a comment

I’ve been implementing some new features and I think it’s ready for an alpha release. I’ll be uploading the files in codeplex.

To follow the MemoDb posts saga:

Now, MemoDb supports:

  • Delete
  • Collections
  • EntityRef (for LinqToSql support)
  • Cascade inserts
  • Cascade delete on collections children (aka all-delete-orphans)

Delete
Pretty simple, it let you delete objects:

using (var s = memo.CreateSession())
{
	var city= s.GetById<City>(1);
	s.Delete(city);
	s.Flush();
}

Cascade Inserts
You can configure MemoDb to insert new references by default:

var memo = new Memo(insertByCascadeByDefault: true)

Or you can specify the behaviour just for one relationship:

 var memo = new Memo()
           .Map<City>(c => c.CasacadeInsert(x => x.Country))
           .Map<Country>();

Cascade Delete Orphans
You can configure MemoDb to delete collections children by cascade when the parent object is deleted by default:

var memo = new Memo(deleteOrphansByCascadeByDefault: true)

Or you can specify the behaviour just for one collection:

 var memo = new Memo()
           .Map<City>()
           .Map<Country>(c => c.CasacadeDeleteOrphans(x => x.Cities));

MemoDb: Auto assign id support

February 4, 2011 Leave a comment

MemoDb is a in-memory-linq-database useful for mocking linq repositories in unit testing. You can track the previous posts:

Today I will talk about the generation of ids for new entities. As MemoDb stands for mocking real linq orms and, generally, the underlying databases auto assign the ids.

var memo = new Memo()
     .Map<MyEntity>(x=>x.Id(x => x.Id, autoAssign: true));

By now, MemoDb supports:

  • Int32: increments the last id.
  • Int64: increments the last id.
  • Guid: Generates a new Guid.

If you need another strategy or to map another id type, you can specify the strategy as a delegate:

var memo = new Memo()
     .Map<MyEntity>(x=>x.Id(x => x.Id, last => last + 10));

In the example above, the generation is made adding 10 to the last id assigned.
By default, MemoDb will assign the ids when the object is inserted. You can override this behavior by configuration:

var memo = new Memo(assignIdMode: AssignIdMode.OnFlush)
     .Map<MyEntity>();

MemoDb: Collections support

February 4, 2011 Leave a comment

MemoDb is a in-memory-linq-database useful for mocking linq repositories in unit testing.
Now it understand how to store collections. The strategy is pretty simple:

  • For class collections (Arraylist, List, Hashtable, etc.) it will construct one of those and add each item. It only works with classes that have a parameterless constructor.
  • For interfaces collections (IList, IList, IDictionary, etc.) it will construct an ArrayList, List, Hashtable or Dictionary according the interface.

You can download the last version from: http://memodb.codeplex.com/

Introduction to MemoDb

February 3, 2011 Leave a comment

I’m working on an internal framework on the company I work (it will be open source soon I expect to post a lot in the future about it) that needs the ability of mocking a repository with a memory database. Since this repository works with Linq, an implementation with a List inside was enough.
The time passed and we realize that it will be really usefull to have transactions in that repository (ok, not so usefull, but at least funny 🙂 ). So I started to work on MemoDb.
The source code of the first version is in http://memodb.codeplex.com.

Let’s show some examples:

var memo = new Memo()
				.Map<City>();


using (var s = memo.CreateSession())
{
	s.Insert(new City
				 {
					 Id = 1,
					 Name = "Buenos Aires"
				 });
	s.Insert(new City
				 {
					 Id = 2,
					 Name = "New York"
				 });
	s.Insert(new City
				 {
					 Id = 3,
					 Name = "Montevideo"
				 });
	s.Insert(new City
				 {
					 Id = 4,
					 Name = "Bogotá"
				 });
	s.Flush();
	s.Insert(new City
				 {
					 Id = 5,
					 Name = "Bangkok"
				 });

}

using (var s = memo.CreateSession())
{
	var cities = s.Query<City>().Where(x => x.Name.StartsWith("B"));

	Assert.AreEqual(2, cities.Count());
}

Note that it doesn’t store Bankgok.

var memo = new Memo()
				.Map<City>();

var buenosAires = new City
{
	Id = 1,
	Name = "Buenos Aires"
};
using (var s = memo.CreateSession())
{
	s.Insert(buenosAires);
	s.Flush();
}

City buenosAires2;

using (var s = memo.CreateSession())
{
	var test = s.GetById<City>(buenosAires.Id);
	test.Name = "Bs As"; //Not flushed!
}

using (var s = memo.CreateSession())
{
	buenosAires2 = s.GetById<City>(buenosAires.Id);
}

Assert.AreEqual("Buenos Aires", buenosAires2.Name);

Right now it supports:

  • Inserts
  • Updates of dirty objects
  • Many-to-one relationships
  • Queries

Next steps:

  • Delete
  • Collection management
  • Id generation strategies
  • Cascade

In future posts I will be talking about the implementation details.

Categories: C#, MemoDb Tags: , , , ,

Magiq-to-Sql: Compiled queries support

November 25, 2010 Leave a comment

Back on the road with Magiq, at least for a while. I’m working on the development of a framework that could make full use of the Named Scopes feature of Magiq. The problem is that linq-to-sql needs compiled queries in order to speed up the performance and the current API is awful. So I tried to give Magiq the ability of handling compiled queries.

Since Linq is all about expression trees, I knew it will be possible to get from

var value = 3000000;
var query = country.Cities.Query( x => x.Population > value)
                          .OrderBy( x => x.Population);

to something like

var value = 3000000;
var expresson = (dc, id, value) => dc.GetTable<City>()
                                     .Where( x=>x.Id == id )
                                     .SelectMany( x=> x.Cities)
                                     .Where( x => x.Population > 100000 )
                                     .OrderBy( x => x.Population);

var query = CompiledQuery.Compile( expression );

Well, two hours of playing with the Expressions and all worked. The only/main problem is that Expressions instances are created every time so each expression object has a different HashCode and it’s impossible to cache the compiled queries by expression. Sadly, I had to add a parameter named “key” for identifying the compiled query.

This si how the final API looks like:

var value = 3000000;
var query = country.Cities.CompiledQuery( "large-cities-by-country", 
                                          (q,p) => q.Where( x => x.Population > p)
                                                    .OrderBy( x => x.Population),
                                          value );
  • The query will be identified as “large-cities-by-country”.
  • We need to pass the expression to be applied to the collection and the parameters, because we don’t want to hardcode the values in the query.

A small benchmark I’ve done with a simple model executing 5000 queries on a new DataContext each gives, this result:

  • magiq – not compiled: 36457 millisecond
  • magiq – compiled: 22295 millisecond
  • linq2sql – compiled: 22194 millisecond

A good name matters

October 1, 2010 Leave a comment

Did you realize that the biggest success of a person called “Gates” is called “Windows”?

Categories: About nothing