LINQ to SQL: Performance and Security

Like many people around the office, I've spent the last several weeks being completely enamored with LINQ. It started out innocently enough with a link to Joseph Albahari's LINQPad and it just took off from there. I'm pleased to say that it has pretty much replaced SQL Management Studio for my purposes. And as an added bonus, it serves as an awesome C# scratchpad. :)

I recall the "good ol' days" when people weren't entirely sure what LINQ had to offer; after all, we already had a decent query language that accomplished the same task! People were already quite proficient with SQL. Why would you need to learn a second query language? What was the point? There is absolutely no excuse to stay in this mindset; if you're not sure what LINQ has to offer, I strongly recommend downloading LINQPad. See it for yourself; there is a lot that LINQ has to offer.

It isn't so much the syntax of the language as much as it is the implementation of all the tools. The instant you connect to a database with LINQPad or generate your LINQ to SQL classes, you'll have a collection of intuitive and easy-to-interact with objects that have well-defined associations to other objects. For instance, an object with a 1:N relation to another table immediately has a collection of strongly-typed items from that other table. A 1:1 relation becomes a typed object; for example, an "AddedByUserId" column becomes an "AddedByUser" object, mapping out based on relationship on the User table. That related object has all of its associations set; suddenly, traversing from one corner of the database to the other becomes much easier.

By intuitively working with the generated LINQ to SQL classes, a lot of work gets done for you. Before I knew it, I had complex queries that were infinitely more maintainable than their SQL equivalents. And they took a fraction of the time to write. In fact, I was able to rewire some of our more complex middle tiers within hours to start taking advantage of LINQ-based queries.

However, despite the colossal benefits I've seen in such a short time, I've encountered a lot of resistance to LINQ. This resistance usually stems from these two reasons:

Myth 1: "LINQ is slow. Dynamically generating SQL queries is a costly maneuver; far moreso than just executing a stored procedure equivalent." This is one of the pitfalls of premature optimization; I've spoken with several people internally who immediately discounted LINQ, saying that it wasn't ready for production code. Not surprisingly, these were people who had no interest in doing their research and had a relationship with SQL that could be best described as unhealthy ;) Rico Mariani has a great 5 part blog post about performance in LINQ (summary here); in a worst case scenario, you're looking at roughly a 7% reduction in performance. Within our group, this is an acceptable tradeoff between performance and productivity.

Myth 2: "LINQ is insecure. Dynamically generating SQL queries means that my attack vector for SQL injection is much greater." This is another one of those healthy knee-jerk reactions; if I'm dynamically generating SQL, then it would make sense that my SQL injection vector is higher. If LINQ is dynamically generating SQL, then this should hold true. But it doesn't. Under the covers, LINQ is breaking down queries into parameterized SQL. Security was a huge concern that was revisited several times in LINQ's development; even through unusual vectors that couldn't be parameterized, LINQ remained a secure way to build out your SQL queries.

I highly recommend taking some time out of the day to learn LINQ; the return on investment is tremendous. Even for something as small as the adhoc queries you make day-to-day, you'll find yourself saving a great chunk of time.