Archive

Archive for December, 2009

There’s not NH vs EF

December 25, 2009 Leave a comment

Today Ayende wrote a post about how EF is better than NH (ok, it is actually about how EF is not better than NH) and I started writing a comment about it when I realized that it was really long and it will fit better in a post. So here it is:

There are two kind of people in .NET world. The ones that likes the language and uses the framework and features following a regular OO development (people that could work in java, ruby, smalltalk, c++, etc) and the ones that does whatever microsoft says, the people that are evangelized. Don’t forget .NET is full of people that worked a lot of time with VB6 and ASP 3.

When .NET cames, it added a pretty good feature, inheritance, and people could start thinking about it. The data access was solved with datasets, that worked a lot like recordset (from the api perspective). But microsoft always suggested to use typed datasets, so developers would use strong typed properties instead of strings. A small step for man, a giant leap for mankind.

Then linq-to-sql came, so you can have objects representing your tables. Each column is “mapped” to a property. Even those foreign keys, but you have also the actual association, so you don’t need to make another select! I think they are educating people and once the developers get used to it, they could remove the fk property from the class. Baby steps, again.

I know, for NH guys all this is trivial, but try to talk about mappings, first level cache, second level cache, inheritance mapping strategies, query cache, multiple databases support, query substitutions, lazy loading, batch size, fetching strategies, custom types, etc. with someone that still thinks from the database schema perspective. Come on, there are people that writes a stored procedure for a simple insert, just because there’s a myth about the stored procedure performance!

There’s not NH vs EF. There’s NH for those that work as community does and EF for the ones that goes to church every sunday morning.

Advertisements
Categories: C# Tags: ,

Magiq-to-sql: Associations issue

December 25, 2009 Leave a comment

Following the Magiq saga, I started working on composite primary keys support for magiq-to-sql. With this feature we will be releasing the first version of Magiq, so we are very exited about it.

The first thing I have to say is there isn’t much information out there, so I use the “try&error” technique. My first approach was to declare the primary keys as several columns with “IsPrimaryKey=true” and, for the associations, using all the columns separated with commas in the ThisKey and OtherKey properties. Of course, I didn’t made up that, I saw it here. Good enough, it worked fine!

But (and there’s always a “but”)… doing the unit tests for this feature I realized we didn’t tested the insert and update of an association. I mean, this:

items.Set( x => x.AReference, x => x.AnotherReferenceOfTheSameType ).Update();

and

items.Insert( x => new Thing{ Reference = x.Reference } ).Into( things );

The problem here is that the generated query for this kind of expressions uses joins and subselects and, since I’m using a different query for each update set or value to insert, linq-to-sql will generate a different where for each (and a the parameters will use different table aliases).

The solution I see is to generate one single select for each property but, as I said here, it needs to use a dynamically generated class. I’m afraid I have no choice. I’ll post about it in the next days. If it works, we’ll be releasing Magiq 🙂

Oh, right, merry christmas.

Magiq: Implementing Magiq-to-Objects

December 18, 2009 Leave a comment

I will continue with the Magiq saga. You can read the previous posts:

Today is the turn of Magiq-to-objects. Having the basic interface needed for the most simple linq-to-sql mass operations, I tried to make it work with objects (ie. using a List as a repository).

The Update:
I thought it would be easy, because all is lamba expression-based. The problem is that I forgot we changed the api, so we don’t have an actual update expression. Instead, we have a lot of property sets:

products.Where( x=> x.ExpirationDate <= DateTime.Now )
        .Set( x=> x.State, ProductState.Expired )
        .Update();

The only way we could actually update a property from a lamda expression representing the getter of the property is using reflection, so we do it that way. Basically, you could inspect the lambda expression until you get to the PropertyInfo object. Having the PropertyInfo, it’s just reflection.

The Delete:
Since we had the where clause, it was easy to compile it and using to filter the enumerable. The problem was I need to remove the items from the original list! QuickWatch helped me again. Basically you have two kind of queries that would be handled by this: EnumerableQuery and WhereEnumerator (or something like that). The first one is what you get when you call the AsQueryable() extension method in a enumerable. The second one is the result of calling the Where extension method.
For WhereEnumerator, there is a private Field called source. You could recursive search it until you get to the main list. For EnumerableQuery, the list itself is like a constant expression inside a big lamda expression. It turned a little messy, but finally we could found the list.

The Insert:
This was the most easy of the implementations. Since the API give us the “new” expression and for the delete we already got the original list, it didn’t give us any trouble.

Bonus track: Dynamic Reflection
We needed a lot of reflection in order to have things working. But we hate reflection. Mostly, because it’s performance. But more because the lack of a good API in linq-to-sql. Ugly or not, we have to use reflection in order to have Magiq working. I googled for something like NHibernate’s reflection optimizer, but what I found wasn’t exactly what I wanted. So we implement some DynamicMethods directly in IL in order to get a respectable performance. This week I will be removing the code from Magiq and I’ll create a new project in codeplex for this. The main idea is to be able to do the same as with reflection, but dynamically.

And this is the story about how we implemented Magiq-to-objects.

Magiq: Updating associations in batch challenge result

December 17, 2009 3 comments

In a the post Magiq: Updating associations in batch challenge I tried to solve an issue with mssql. Basically, I wanted to update 2 tables in the same query, because the update itself changes some columns used in the where clause. Greatfully, it had several answers that led me to a solution:

There are two kind of property sets: the ones that invalidates the where clause and whe ones that doesn’t. Since there’s a way to find out if a property expression is used in another expression (visiting the expression tree or just manipulating strings), it’s easy to mark them. Magiq should execute first the ones that doesn’t invalidate the where clause. For the invalidating ones, I will use a table variable but if there’s only one of them, then it will execute a single update (because there’s nothing else to update). I’m not worried about using table variables, because in other databases the feature is fully supported.

Thanks to everyone that commented yesterday, it was very helpful!

Magiq: Inheritance support

December 17, 2009 Leave a comment

Magiq now supports inheritance! So, you can do:

items.Where( ... ).Insert( x => new SubClass() ).Into( BaseClassRepository );

It was always supported by magiq-to-objects. However, it’s supported now by magiq-to-sql. It was pretty simple to implement, though.

Categories: C#, Magiq Tags: , ,

Magiq: Updating associations in batch challenge

December 16, 2009 20 comments

Today I started working in a new Magiq feature, batch update of associations.
The idea is to be able to run this:

contacts.Where( x => x.FirstName == "Ivo" )
        .Set( x => x.City.HasPeopleNamedIvo, true ).Update();

I know the example doesn’t make any sense, but it’s fine for the explanation purpose.
It was easy to implement in Magiq-to-objects (it needed some expression manipulation, but harmless). The problem begun when I tried to update a property used in the where condition using magiq-to-sql. Basically, for this magiq sentence:

contacts.Where( x => x.FirstName == "Ivo" && !x.City.HasPeopleNamedIvo )
        .Set( x => x.FirstName, "IvoWiblo" );
        .Set( x => x.City.HasPeopleNamedIvo, true )
        .Update();

it’s generating these queries:

UPDATE [Contacts] SET [t0].FirstName = @p1
                FROM [Contacts] AS [t0]
                LEFT OUTER JOIN [Cities] AS [t1] ON [t0].CityId = [t1].Id
                WHERE [t0].FirstName == @p0 AND [t1].HasPeopleNamedIvo = @2
UPDATE [Cities] SET [t1].HasPeopleNamedIvo = @p1
                FROM [Contacts] AS [t0]
                LEFT OUTER JOIN [Cities] AS [t1] ON [t0].CityId = [t1].Id
                WHERE [t0].FirstName == @p0 AND [t1].HasPeopleNamedIvo = @2

EDIT: I changed a little bit the queries just to reflect that “changing the order of the sets” is not the solution.

As you can see, once the first SQL is executed, the second one updates nothing, because there’s no more people with that FirstName.

I have not idea how to solve it, do you?

HasPeopleNamedIvo

Disposable should dispose, right?

December 15, 2009 Leave a comment

Doing some unit tests for magiq-to-sql I found this issue: DataContext.Dispose() doesn’t close (nor dispose) the active connection. Can you believe that?
This is how I had to write the code in order to make it work:

var c = dataContext.Connection;
if(c.State != ConnectionState.Closed)
     c.Close();
dataContext.Dispose();   
c.Dispose();

This is what I call annoying.

Categories: C# Tags: