Beginners should not use LINQ
When I first heard of LINQ I got really scared. I could see that it was a very powerful tool but also a tool that would be easy to abuse. Most experienced developers tend to agree that putting SQL statements into your logic or even GUI code is a bad design. Beginners tend to realize this pretty soon too. But with LINQ we get the opportunity to do the same kind of bad design once again. And since it is ".Net code" rather than "SQL statement" I had a fear that it would take longer before the beginners learned their lesson. And why do I care? I don't know. Guess I'm just one of those guys who want everybody to do a good job.
Since LINQ was introduced I have not really seen LINQ in action very in any real code so I kind of forgot about this. But then I read this. Looks like I was right. LINQ is being abused just in the way I feared. But I'm happy to see that a person who I've heard speak warmly about LINQ so many times finally points out how LINQ can be your gate to bad design. And remember to read the comments too when you follow the link above. The topic unfolds...
UPDATE: Not only did the topic unfold in the linked thread. It unfolded here. If you just found this page I strongly suggest you read all the comments.
Comments
Anonymous
October 17, 2008
Respectfully... I completely disagree: beginners should learn LINQ. Beginners must learn to write maintainable code, and LINQ -- to anything -- is one of the best ways to writing short, exceedingly maintainable code that does precisely what you think it should. There is zero difference, maintainance-wise between using methods on an in-memory domain model and using methods on an IQueryable. None. The code is precisely the same. Done propertly, the UI doesn't even know what's underneath an IQueryable. There are an unfortunately number of entrenched, nigh-cultish alpha geeks needing to rethink design in a world where you're not passing around some string being cobbled together into a SQL statement. That is the source of problems in the old world and why DALs came into being. But, using LINQ to SQL, that situation does not exist and the old cautions do not apply. Think first about why design dogma came into being before making such broad statements about what is right and proper for beginners.Anonymous
October 17, 2008
I not fully agree with your opinion. First, a beginner or a bad developer will always write bad code whatever the language and the plateform. LINQ is no more dangerous than operator overriding, interfaces or any "smart" language feature that are necessary (no professional software can today be developed using MS interpreted Basic of the 70's...). Secondly I think you're making the mistake a lot of people is making: LINQ is definitively NOT a database technology. LINQ To SQL or LINQ to Entities are just two flavours of LINQ. LINQ To XML, LINQ to Object, LINQ to Datasets, etc are not linked (directly) to any database. Thus, LINQ is NOT SQL in any way. At first glance it "can" look like a "kind of" SQL. But it is a very (very, I said very ?) limited sight of what LINQ is really. So, I would say that every beginner must learn and practice LINQ because a good C# 3.0 code is made of LINQ for everything (listing files in a directory, knowing which process is using the most memory, looping through controls on a forms to init them, etc, etc...). Of course, C# 3.0 is far more complex to master than C# 1.0, it is more subtle, it allows for more smart code. That's the core of our job : learning and learning again the new technologies, new languages, new plateforms ! Farther I'll say that someone, even a beginner, that can't understand and learn LINQ (like any C# 3.0 additions) must change its job plans and look for something easier, plumber, butcher or some manual job (and valuable, I'm not saying at all those profession are "less" interesting or "less" valuable. The world is needing all talents). So, LINQ can lead to bad design as any other C# 3.0 features. Wanting to see LINQ as something that can be ignored, as a "plugin" is not the right way to see things : LINQ is C# 3.0 like lambda expression or anymous types. You can't say you're a professional if you plan to use just the features of C# 3.0 that make it looking like interpreted Basic of the 70's... I really think you must reconsider your point of view about LINQ. Sincerely.Anonymous
October 17, 2008
The comment has been removedAnonymous
October 17, 2008
@odhan: I can agree that I probably should have been more clear from the beginning that it is LINQ to SQL that is my main concern. On the other hand I thinkthis is the most common use of LINQ by beginners. "Beginners should learn LINQ but be careful use LINQ to SQL since it is a risk they use it wrong and end up with a bad design" would probably have been the best title for this post. And you're completly right that LINQ is not the only powerful tool that can easily be abused and used to create a bad design (some people don't even need fancy tools to create bad designs). So I guess I have a whole new list of posts I must make. There are lot of things beginners should not use until they fully understand their consequenses. :-) On a more serious note. If a beginner does not use these tools, how can they learn them? Experiment! Talk with more experienced developers. Learn from others with more experience. Soon you're no longer a novice and start using the tools in a good way. And then I'm happy...Anonymous
October 17, 2008
I agree, ofcourse :) While, as stated in the comments, a well managed solution with IQueryable will hide the storage details it is still important to honor old design principles like DRY ( Don't Repeat Yourself) and Separation of Concerns. They apply even to solutions with LINQ. As I state in my post; LINQ is still a query language, although typed and integrated with C# / VB, and queries as such have a place in the application design. You shouldn't spread it all over your applications. Maintainability will be a mess. I also don't agree that it's the nature of T-SQL strings that drive forth the design pattern to use DAL's. It's there because Separation of Concerns is important and that principle applies to all your development. Don't mix cache code with databinding, don't mix data access with bussiness logic, don't mix bussiness logic algorithms with event handlers, and don't mix query syntax with other kinds of code. As Robert C. Martin states, a module should have /one/ reason to change.Anonymous
October 17, 2008
Oh and, of course beginners should learn and use LINQ, but as with any other technology they should properly learn it with all the best practices and design principles there.Anonymous
October 17, 2008
Patrick, cellfish: You fail to state how LINQ to Objects differs from LINQ to <some IQueryable, or any other> in terms of maintainability. If you accept the first, how would you justify denying the second? Relying on Martin, Fowler, or any of their works -- which may have been perfectly valid (and I'd certainly agree in Fowler's case) informative in the past -- does not much bolster your argument for the present. The approach LINQ takes means that a module does not have to be changed just because something underneath has: this was one of the primary motivations for LINQ to begin with. If you want to insulate yourself from changes in the shape of the data you get back from your data source, there are perfectly LINQ-ish ways to do that. LINQ to Entities, for example, is designed specifically with that in mind in the case of relational databases. So I don't think there is any validity in saying "Thou shalt completely barricade thy UI from LINQ to SQL.". Indeed, I think that's an entirely self-limiting inertia that kills any actual progress toward solving the true problem. We already have sufficient abstraction (in the form of IQueryable and IEnumerable) that UI, etc are protected. If you find yourself in a situation where the underlying data model needs to shift independently of the application's view, then the answer doesn't lie in fearing LINQ -- it lies in changing which LINQ provider you make use of (eg, LINQ to Entities, or some other mapping technology). There is one thing I would support in LINQ to SQL: a minimal layer that only instantiated a data context, and instead of exposing Table<T>, exposed IQueryable<T>. Feel free to pass around the IQueryables, because they will save your application's perf without stringing spaghetti all over. And that is what I'd teach -- not fear of LINQ to SQL, or even fear of LINQ in a UI, but awareness of how to use LINQ such that you can change technologies without losing LINQ's ability to, for example, push those UI operations (sorting, paging, etc) back to the data source, where they belong.Anonymous
October 19, 2008
@kfarmer: The difference is small and the reason LINQ to "omething other than SQL" is that since it is not SQL I believe the risk of using LINQ as a replacement for SQL is smaller thus reducing the risk of a bad design because of a newbie misstake. For me it is the resemblance between SQL och LINQ syntax that is the danger here. Interesting that you mention a minimal layer providing abstraction. That is an important aspect for me in this case since that layer of abstraction probably is enough to achieve a reasonable level of maintanability. Naturally depending on how that is implemented and used. Interesting also that you mention application performance. I'm a strong believer that "premature optimization is the root of all evil" and that is why I refrain from choosing a design for performance reasons if there is a better design from a maintanability perspective. Last I must disagree that IQueryable and IEnumerable are suficient abstraction for the UI in them selfs. For me it is not the interface it self that defines level of maintainability. It is rather how that IQueryable is obtained. Usually you want to select data using some kind of filtering and these properties (whatever they are) often turn out to be of "magic values" for the GUI. They are strings and values that "just have to be something" in order to make the query work. In these cases I think it is bad to have those magic values in the GUI. If you however use LINQ in the GUI to query the service facade for a number of business objects, I personally don't have a problem with that if it is done right. The reason for my initial post on this topicis that I think it is hard, especially for beginners, to make that call. And if it is hard I think it is better to go for a safe bet instead of confusing the beginner.Anonymous
October 20, 2008
The comment has been removedAnonymous
October 20, 2008
The comment has been removedAnonymous
October 20, 2008
@kfarmer: IQueryable is not a sufficent abstraction. LINQ is still a query and should be handled as such. Queries change, queries need to be maintained and thus they should do so in a separate layer, as any other part of your application. With that said, IQueryable is not really that innovative. What's innovative is how the compiler handles the magic that goes with it. The patterns that IQueryable follows has been around for years but without the slick language integration that it now got. LINQ doesn't change how applications should be written, it just makes querying a little easier. Basic software engineer principles still apply and one of those principles is Separation of Concerns which bluntly led to the idea, amongst other, that UI's should not hold any logic but that needed to present. Querying, no matter what you query in-mem or database, is not part of the UI responsibility and should not be there. Or are you arguing that basic layering and separation of business logic and algorithms no longer apply because "LINQ" will take care of that? No my friend, LINQ is about querying not a paradigm shift. Querying made simple and partly abstracted away from the source I agree, but it still is querying, you still need to follow the basic principles of software engineering that has been around for 40+ years and survived all new technology breakthroughs.Anonymous
October 20, 2008
BTW, I am pragmatic, If all you got is a couple of queries and one or two classes, the basic YAGNI rules apply as well of course. But for any major system you don't want to mix responsibilities, no matter what kind of slick technology support you got.