Archive

Archive for April, 2011

Magiq: New release and API Changes

April 28, 2011 Leave a comment

New release of Magiq, supporting Linq-to-sql. This should be the last one for Linq-to-sql, the next one I hope will have the minimal support for Entity Framework. You can download it from here.

For those reading this for the first time (?), Magiq is a framework that let you do mass operation in a Linq fashion.

So… as Magiq will be supporting Entity Framework soon, it made sense to change the API to make it support Entity Framework limitations. Also, I found a better Insert API (the one that always made me doubt!). The changes are:

Query extension method changes
The new method looks like this:

country.Query(x => x.Cities); 

It will return an IQueryable that will let you do all the Magiq stuff.

No more IEnumerable support
This is a hard one. You can only do Magiq stuff between IQueryables. If you have an IEnumerable collection, use the Query extension method of it parent entity.

New Insert API

destination.Insert( source.Where( condition ).Select( new Item{ ... } ));

Cool, isn’t it? 🙂

Entities extension methods
Because we no longer support extension methods over collections but over the entity, there are some extension methods for improving the code readavility.

Delete

entity.Delete(x => x.Collection.Where( condition ));
//Instead of 
entity.Query(x => x.Collection).Where( condition ).Delete();

Update

entity.Update(x => x.Collection.Where( condition ).Set(x => x.Prop, value));
//Instead of 
entity.Query(x => x.Collection).Where( condition ).Set(x => x.Prop, value).Update();

Query

entity.Query(x => x.Collection.Where( condition ));
//Instead of 
entity.Query(x => x.Collection).Where( condition );

Insert

entity.InsertInto( x => x.Collection, source.Where( condition ).Select( new Item{ ... } ));
//Instead of
entity.Query(x => x.Collection)
      .Insert( source.Where( condition ).Select( new Item{ ... } ));

Weak Dictionaries

April 25, 2011 1 comment

Suppose you need a complex/slow process for generating something and you want to cache it. But you don’t know if that something will be used a lot of just a few times. If it is the last case, you don’t care executing again the process, but it’s different if it’s accessed several times.

WeakDictionary to the rescue!

This dictionary, basically, maintains each value in a class that could reference it as a weakreference if it wasn’t accessed often and if the amount of items is bigger than a threshold defined:

var d = new WeakDictionary<int,SomeClass>(3);
d.Add(1, new SomeClass());
d.Add(2, new SomeClass());
d.Add(3, new SomeClass());

//We use the values...
var bla = d[1];
var bla1 = d[1];
var bla2 = d[1];
var bla3 = d[2];
var bla4 = d[2];
var bla5 = d[3];

//When we try to add an item and we are passing the threshold, it will weak the less used reference
d.Add(4, new SomeClass());

d[3] value is now maintained with a weak reference. If it’s used before it’s garbage-collected, it will be alive again and d[2] will be the “weak one”.

You can download the code here.

Categories: C# Tags: ,

Magiq: Next steps – different approach

April 25, 2011 Leave a comment

Back to the Magiq game!

I started to play with Entity Framework 4 and realized some stuff is not possible the way it was designed. It has to do with the way EF4 manages Lazy collections.
In Linq-to-sql and NHibernate, the collection itself has the property of being lazy, materializing all the objects when you iterate it. For example, in Linq-to-sql collections are EntitySets. Because of this, you can do this:

parent.Children.Delete(x => x.SomeCondition);

This is because the Children collection contains all the information needed:

  • The parent object instance, for getting the Id
  • The collection name

Sadly, EntityFramework handles this feature in a different way: Is the parent object the lazy one and the collection is populated when you access the collection propery and not when you iterate it. Because of that, in the moment you do parent.Children you have executed the query in the database.
This lead us to have a different API, that avoid accessing the collection property. What I thought is:

parent.Delete(p => p.Children.Where(x => x.SomeCondition));

It’s not so bad, I must Say, and it also let us do things like

parent.Delete(p => p.SomeObjectInTheMiddle.Children.Where(x => x.SomeCondition));

without executing the query for getting the SomeObjectInTheMiddle instance.

Also, I give up with Magiq-to-NHibernate, at least for a while. NHibernate has huge features, it let you map your classes in thousand of different ways, and that is awesome. But also it makes it really complicated to work with. And since NHibernate already has mass operation support, it makes sense to stop worring. At least, as I said before, for a while.

So, I will be working on changing the Query API and only for Linq-to-Sql and Entity Framework. Everyone is welcome to contribute implementations for other ORMs.

Next step: Changing the API