# Monday, April 27, 2009

A few weeks ago I made a major course correction in our choice of ORM data layer. We had planned to use LLBLGen Pro but several issues with the code that it generates continued to bother me. First, it's support for stored procedures lacked the ability to strongly type the resultset. Second, the data entity classes do not easily support serialization over WCF with the option to dress them up with the appropriate attributes.

So I took a second look at PLINQO with CodeSmith 5.0, something I had considered some time ago but had decided against because I felt it was not sufficiently mature for our team's use. I wanted to see if the dev team had improved the product to the point that I believed it would work for us. I'm very happy I gave it another try. They have done a great job and restored my confidence in LINQ to SQL.

With PLINQO, I found that I could return to standard LINQ to SQL queries and enjoy many of the benefits I had looked forward to using in LLBLGen Pro such as "disconnected" entities. And much to my satisfaction, PLINQO resolves the two major issues I had with the LLBLGen Pro. The improvements over standard LINQ to SQL may seem small at first but when dealing with a very large, enterprise class database, the enhancements that PLINQO offers are critical, including the separation of entities into individual class files.

There are many more features and benefits with PLINQO than I have time to review here. If you're looking for a better LINQ to SQL than LINQ to SQL, look very carefully at PLINQO. I mean, who couldn't fall in love with code like this all buttoned up for you automatically:

private long _userId;

//// <summary>
/// Gets the USER_ID column value.
/// </summary>
[System.Data.Linq.Mapping.Column(Name = "USER_ID", Storage = "_userId", 
     DbType = "bigint NOT NULL IDENTITY", IsPrimaryKey = true, 
	 IsDbGenerated = true, CanBeNull = false)]
[System.Runtime.Serialization.DataMember(Order = 1)]
public long UserId
{
    get { return _userId; }
    set
    {
        if (_userId != value)
        {
            OnUserIdChanging(value);
            SendPropertyChanging("UserId");
            _userId = value;
            SendPropertyChanged("UserId");
            OnUserIdChanged();
        }
    }
}
Wednesday, April 29, 2009 8:17:14 AM (Mountain Daylight Time, UTC-06:00)
Attribute based mapping, change notification, magic strings, why would I want to pollute my entities with such nonsense? I'll pass thank you.
Travis
Wednesday, April 29, 2009 8:57:17 AM (Mountain Daylight Time, UTC-06:00)
Travis, thanks for the comment, but please share with us your preference. -Tyler
Tyler
Wednesday, April 29, 2009 11:30:17 AM (Mountain Daylight Time, UTC-06:00)
I tried to email Travis to invite him to elaborate, but he gave an invalid address. Can we derive anything useful from that? I'd really like to hear what his and reasoning recommendations are.
Tyler
Tuesday, May 05, 2009 5:32:04 PM (Mountain Daylight Time, UTC-06:00)
For the limited code you posted, this would be my same class in its *entirety*.

public class MyClass
{
public long UserId {get;set;}
}

No "change notification", no attributes, and no magic strings, just a simple POCO with no code generation needed. (I wont go into why I do not like Code Generation)

How do I accomplish this with my domain entities and my database? NHibernate, and Fluent-NHibernate.
Travis
Tuesday, May 05, 2009 5:54:21 PM (Mountain Daylight Time, UTC-06:00)
Travis, thanks for the elaboration. It's good to know what your preference is.
Tyler
Tuesday, May 05, 2009 6:08:01 PM (Mountain Daylight Time, UTC-06:00)
in my opinion, the entirety of ORM is nothing more than the Vietnam of programming. From everything I have seen and heard, it sets out to solve "problems" that are floating abstractions with no basis in reality. It's one of those things that is good "in theory"... like communism. I have yet to see one legitimate, concrete, real-world problem that ORM ACTUALLY solves. For every alternative it offers, it CREATES two more legitimate problems that didn't exist without it.
Kevin W.
Tuesday, May 05, 2009 6:09:02 PM (Mountain Daylight Time, UTC-06:00)
Interestingly, Fluent NHibernate does generate code for you: http://wiki.fluentnhibernate.org/show/GettingStarted%3A+Introduction
Tyler
Saturday, May 30, 2009 8:24:57 AM (Mountain Daylight Time, UTC-06:00)
More on this topic, worth a read.

@Typer, FH does not generate code for you, it's just another way to express your NH config in a strongly typed manner. More errors are caught at compile time vs run time like the old XML config.
Travis
Comments are closed.