Wednesday, February 15, 2012

Why Can't LINQ Tell Me Where It Hurts?

I ran into an interesting issue with Linq to SQL today. Apparently if a table doesn't have a primary key, the data context can't write updates to it. This makes sense, of course, given that without a unique identifier the entity has no way to uniquely identify a record. That part didn't bother me. (The fact that the data modeler has tables without keys, or without constraints of any kind bothers me. But that's immaterial to this discussion.)

What bothered me was that the Linq entity code just silently failed. No errors, no nothing. The value was 1. I set it to 2. I checked that it's now 2. I submitted changes. Nothing. SQL Profiler shows that no UPDATE command was sent to the database. No error. Nothing.

What the crap, Microsoft?

After tracking down the bug and getting a primary key added to the table, I did a diff on the old auto-generated entity code vs. the new auto-generated entity code to see how the properties changed.  For comparison...

Entity property without a primary key:
public string Name
{
  get
  {
    return this._Name;
  }
  set
  {
    if ((this._Name!= value))
    {
      this._Name= value;
    }
  }
}

Entity property with a primary key:
public string Name
{
  get
  {
    return this._Name;
  }
  set
  {
    if ((this._Name!= value))
    {
      this.OnNameChanging(value);
      this.SendPropertyChanging();
      this._Name = value;
      this.SendPropertyChanged("Name");
      this.OnNameChanged();
    }
  }
}

So the code generator knows that there's no primary key. It uses a different template for the properties in response to this fact. So why can't they take it a step further and make the property a little more informative of this knowledge?

Something like this:
public string Name
{
  get
  {
    return this._Name;
  }
}

Or perhaps this:
public string Name
{
  get
  {
    return this._Name;
  }
  set
  {
    throw new SomeKindOfException("Can not update values on a read-only entity collection.");
  }
}

Or even this would be a step in the right direction:
/// 
/// Gets or sets the Name property.
/// NOTE: Entity collection is read-only, so updated property values
///       will NOT be saved to the underlying data source.
/// 
public string Name
{
  get
  {
    return this._Name;
  }
  set
  {
    if ((this._Name!= value))
    {
      this._Name= value;
    }
  }
}

Again... What the crap, Microsoft?

Thursday, February 9, 2012

ClosedXML

Remember when I needed a way to write to an Excel file?  COM sure is ugly, but it worked and I was happy with the results.  Turns out I needed to do something similar again.  And, well, COM is still ugly.  And it was getting really ugly this time.

In my original code, it was a thick application running on a workstation.  So working with the already-installed Excel instance was fine.  This time, however, it was going to be in a web application.  It needed to open a known template Excel file (which contains VB macro code), write some data to a known sheet within the file, and deliver the file to the user.  (NOT save it.)

So the problems included:
  • Excel has to be on the server.  (Which also presents potential licensing issues.)
  • If there's an error, Excel might show an error on the server.  Which is terrible.
  • The COM code is designed to work with files, and to save those files.  I couldn't find a way to turn an in-memory unsaved "file" into a stream with COM.
  • etc.
The first version worked, but it was still using COM which still had the above problems.  I could open the file, write to it, save it to the host's temp directory, then read it into a stream from the file system and serve it to the user.  Since the file was in the temp directory, the host would eventually clean it out anyway.  So I didn't need to care about leftover files.

But seriously, writing it to a file?  It felt like it got ugly fast.  But this cloud had a silver lining.  The Excel file, even though it was polluted with VB macro code, was an OpenXML file.  So, following the advice of a colleague, I looked into using OpenXML to manipulate the file in-memory and hopefully try to return it as a stream.

Or so I thought.  Have you ever used the OpenXML API?  I use the term "API" very loosely here.  You need to know a lot about the structure of the XML to do anything.  If you don't, it'll just break.  You'll write data to the file, save, etc.  But when you try to open the file, Excel will just yell at you and then remove anything in the XML that it didn't like.  Just look at Microsoft's examplesAll of that code is needed just to write a single value to a single cell.

So after spinning my wheels on OpenXML for a while, and cursing XML in general, what I ended up with was pretty much the same thing.  Better in some ways, worse in others.  The server no longer needed to rely on Excel, which was fantastic.  But the code was huge and ugly and would be damn near impossible to support, especially for the junior developers who are going to be supporting it after I'm done with this project.

Then, out of nowhere, one of my Google searches turned up something wonderful... ClosedXMLThis is an API.  It basically abstracts OpenXML into a nice, simple, more object-oriented interface.  So you don't have to intuitively know the placements of the XML tags in the document format; You don't have to remember the difference between a Worksheet and a WorksheetPart and WorksheetData or whatever; You don't have to know to put strings in a special place in the document and then reference them elsewhere (seriously, what the hell was that?); You can just open the document and write to it.

And you could save it to a stream.  So I didn't have to write it back out to the file system temporarily, introducing another point of failure.  Bonus.

So now my code to open a file, write a value to a cell, and return it as a stream is simply...

public byte[] GetExcelApplication(Guid sessionKey)
{
  var workbook = new XLWorkbook(_excelFile);
  var worksheet = workbook.Worksheets.Where(w => w.Name == "Session Key").Single();
  var cell = worksheet.Cell("A1").Value = sessionKey.ToString();

  using (var ms = new MemoryStream())
  {
    workbook.SaveAs(ms);
    return ms.ToArray();
  }
}

Much better.  Now I'll throw in some input and output checking, test for resource leaks and add "using" blocks accordingly, and we're good to go.

Wednesday, February 8, 2012

Why a Career Can Suck if You Make it Suck

A colleague came across this old blog post yesterday, in which some random blowhard rants about how computer programming is a terrible career.  It's a long and somewhat painful read, but I still read it.

As another colleague put it, this person proves the adage: "Blogging is not writing. Blogging is graffiti with punctuation."  (Or so I wrote on my blog.)  And, despite the irony of following in kind, this is very much true.  The author is simply ranting to anybody who cares to listen, offering no real substance.  (Again, the irony of me saying this is not lost.)

Now, to be fair, there did exist the occasional nugget of insightful commentary in that rant.  But the noise to signal ratio was a bit high to really glean much from it.  I'll see what I can do, though...

Temporary Nature of Knowledge Capital

In this section the author describes the plight of the computer programmer in an ever-changing world of skill sets.  It's a challenge we face as an industry, that much is true.  But statements like this give me pause:
"I’d make the case that it’s better to hire the 27-year-old because he is still at the stage of his career where he enjoys the stuff and is therefore more motivated to learn and work harder, while the 60-year-old is surely bitter about the fact that he’s getting paid less than the younger programmers."
What the author basically just said was that old people are stupid and angry and shouldn't be hired.  No wonder he sees the career as a dead end.  He assumes that, as he gets older, he's not going to want to learn or do anything anymore.  Hopefully nobody makes the mistake of hiring this guy, because apparently his plan is to stop developing his career.  And here's a clue as to why this is his plan:
"Because of the temporary nature of the knowledge capital, computer programmers quickly reach a stage in their career when their old knowledge capital becomes worthless at the same rate as they acquire knew knowledge capital. Their total knowledge capital is no longer increasing, so neither does their salary increase. They have reached the dead end plateau of their career, and it happens after less than ten years in the field."
Apparently he thinks that, after being in the field for ten years, he's learned everything he'll ever need to know.  And apparently he thinks that the tools he uses are the only things he can learn.  Forget things like design patterns or language constructs in general, he seems to only know or care about a tool.  And he plans to forget how to effectively use his tools as he learns new ones.

I think I have an idea as to why his salary is no longer increasing.  It would appear that he's getting old and has decided that he can't improve anymore.  Well, that's why other programmers get paid higher salaries.  They continue to improve.  It's called competition.  Get used to it.

Low Prestige

He opens this section with this:
"Computer programming is a low prestige profession. This is evidenced by the fact that people from affluent families rarely go into computer programming but instead will seek out the more prestigious professions such as law, finance, and medicine. Of course there are some exceptions. There was a programmer who worked for me whose father was a doctor. But more typical was another programmer who never finished college and whose favorite hobby was hunting."
This isn't low prestige.  This is low self-esteem.  So... the guy whose father was a doctor has some kind of different educational and/or social status than the guy who liked to hunt?  I'm sorry, I don't see it.  Maybe by coincidence these two people did come from very different rungs on the social ladder, but the author seems to think it has something to do with doctors and hunting.  Sounds to me like he came from a less affluent family and he's just mad about it.  You're an adult now, buddy.  Get over it and move on.

Then there's this gem:
"There is a prestigious school, the Massachusetts Institute of Technology, devoted to science and engineering, and while I’m sure that there are some students there who are majoring in 'computer science,' the science that’s taught isn’t related to the dirty low-prestige job of creating e-commerce websites using ASP.NET. On the other hand, practical computer programming is a popular major at bogus for-profit schools like Devry 'University' and the 'University' of Phoenix."
Wow.  Just... Wow.  He's right about one thing... Universities often don't teach courses in grunt work application development.  This seems to go back to his earlier implication that there's nothing else to learn in software development other than how to use a tool.  (Or, to put it more bluntly, how to drag a little picture onto a design surface, set some properties, and pretend you just did something difficult or interesting.)  No, I'd much rather see universities spend time on something a little more... academic.  Theory, design, software life cycle, core concepts, all those lovely things.

Again, it sounds to me like this guy is just self-loathing here.  He didn't come from money, and he's mad about that.  He didn't go to a big name university, and he's mad about that.  Etc.  Throwing in that jab at schools like DeVry and UoP isn't really constructive either.  So, to add to his earlier point about how there exists only ten years worth of knowledge to be learned, he's now saying that it all depends on where one went to school.  Horse shit.

Again, the author needs to grow up and be a professional.  Within a couple years of leaving school, the school no longer matters.  At all.  Does his education still take up a third of a page on his CV like it does with junior developers?  People who have been in the industry for ten years or more barely even mention it.  The degree received along with where and when it was received is nothing more than a footnote on a professional CV.  But then, he apparently doesn't learn anything new to advance his career, so what else would he add?

To further support his argument, he quotes a student:
"As a Chinese immigrant at the University of Virginia wrote, 'whatever your position is, as a CS person, you are socially classified as a geek. At my school, University of Virginia, being a rich frat boy and having a future in investment banking or law gets you a lot further status-wise even though you may not necessarily be paid more.'"
Allow me to translate... "I'm a college student who studies some kind of science.  People call me a geek.  Jocks are more popular.  That's not fair."  Note that, in his argument about how a career in computer programming sucks, he is supporting his views by quoting a student, someone who hasn't had a career in computer programming.

The Foreignization of Computer Programming

This entire section basically boils down to... "There are too many damn Indians in programming.  I hate that."  At one point he steps aside for a moment to explicitly state that he's not trying to sound racist and that the "foreigners" with whom he's worked are nice people.  Now, see, he wouldn't have to explicitly try to defend himself as not sounding racist if he didn't sound so damn racist.

But let's not play the race card.  Let's take a look at things he actually says:
"Computer programming (along with nursing) has been specially targeted by our government for foreignization."
Citation, please?  I didn't think so.  Granted, this was written a few years ago and off-shoring was big at the time.  My observations in recent years tell me that it's been dying down a bit because the total cost of ownership from always going with the lowest bidder is starting to make its way onto people's spreadsheets, and perhaps software quality will start to become a more important factor as a result.  (Uncle Bob just smiled when I typed that, I'm sure of it.)  So, as I mentioned at the beginning, there was a faint glimmer of a point to be made in this ramblings.  But he failed to effectively make it.

Project Management Sucks Too

This was the section that I feel had the most potential for insightful content.  The author's mistake here, however, is that he opens with this:
"In order to escape a job where the future is bleak for older programmers due to the rapid depreciation of computer programming knowledge capital, computer programmers face the need to move up to management or likely wind up as underemployed fifty-year-olds, only suitable for lower paying IT jobs like 'QA' because they no longer know how to use the latest and supposedly greatest programming tools."
So he bases the entire argument upon an earlier flawed premise whereby he assumes that there is no further upward mobility for a programmer once he's been writing code for ten years.  I assure you that there is.  (Not to mention that he demonstrates a complete and utter disrespect for QA professionals, which just further solidifies my observation that he doesn't actually know much about software development and is nothing more than a code monkey who picked up a book on .NET, dragged controls onto forms for a few years, and never learned anything of substance.)

I do like his observation about how project managers aren't really "managers" in the corporate organization chart sense.  In my experience that is often the case.  So I can see where it's a bit of a misleading title.  I have a kind of a love-hate relationship with project management.  I hate doing it, and I love working with someone who's good at it.  He's right when he says that writing status reports blows.  And he comes close to making a good point when he says that upper management values project management simply for those reports and charts and graphs that make upper management feel happy.

Now, of course, there's a lot more to project management than just writing status reports.  (At least there is for real project managers, not random business folks who are just given the title of project manager.)  Tracking work items, clearing road blocks, maintaining communication across teams and disciplines, and in general facilitating the work of the other members of the team.  (Apologies to any project managers who want to modify or add to that list.  I genuinely don't know a lot about project management, and I'm really glad that you do.)  This is invaluable.  Putting a bunch of programmers into a room, no matter how good they are, does not ensure good results.  Adding a project manager to the mix does not, by itself, ensure good results either.  But that doesn't invalidate the position.

He's right about one thing... If one doesn't want to make the transition from programmer to project manager, then one shouldn't attempt it.  Indeed, if one doesn't even know what project managers do, then one shouldn't volunteer to be a project manager.

In the midst of all of this nonsense, however, he does make one really good point:
"This trend, in which people without computer programming experience manage computer programming projects, is a result of the low prestige of computer programming. People with high prestige jobs, like surgeons, would never allow themselves to be managed by non-surgeons. In a complicated medical procedure there will be a head surgeon overseeing the surgery, and not a project manager without any medical training. Lawyers have Model Rule 5.4 which makes it unethical for non-lawyers to manage lawyers."
This reminds me of Robert Martin's ongoing point (or perhaps even crusade) about how, as an industry, we need to become better at self-regulating.  (Yes, I mentioned his name twice in one blog post.  It's not fanboyism, it's just that his writings have brought forth a lot of good points about the industry in general.)  Indeed, it always bothers me when technical decisions about the software are being made by non-technical personnel.  (Or, even worse, by former technical personnel who failed to advance their technical careers and just went into management by default as a result of seniority... which I feel is the author's path, unfortunately.)  We do need more crossover between skilled developers and skilled management, because the reality is that non-technical personnel (the people who created and continue to run the majority of businesses which employ us) call the shots.  Many of them are even very good at calling the shots, and have successful businesses to prove it.  But in their calling of said shots, they need someone who speaks their language.  They are under no obligation to learn anything about software development, and it's our job as professionals to communicate our recommendations and requirements effectively.

The Working Conditions Suck

This can happen anywhere, honestly.  My mother works in a grocery store, and the conditions suck.  A friend of mine is a police officer, and the conditions suck.  It's more about the employer than the industry.  Yes, programmers are often left behind when it comes to office working environments.  This is, of course, not unilaterally true.  But, as with any profession, it does happen.  This is why it's important to continue to improve one's skills and professionalism, so one can find better jobs.  If, as is the case with the author's original premise, one simply gives up on learning anything new and stagnates in one's career, then one shouldn't be at all surprised that one can't find better opportunities.  Perhaps instead of just blaming the industry and whining about it, the author should take some initiative and advance his career.

For a look at the author's professionalism, let's see what he says here:
"If you walk over to the graphic arts department, you will see really big monitors. The graphics people could surely make do with smaller monitors, but even though they make less money than computer programmers, they have been able to convince higher level management that their work requires better hardware. When computer programmers request better hardware, they are often seen as whining geeks who just want to waste the company’s money on unnecessary high-tech toys."
Writing is a text-only medium, so tone can be difficult to convey.  Was he being sarcastic, or did he genuinely just say that "the graphics people could surely make do with smaller monitors"?  In his plight for better working conditions, he just did the exact same thing that he claims other departments are doing.  He claimed that "those guys don't need it, I need it."  I would think a better point would be that everybody needs it.  That's part of being a professional... respecting other people's jobs.

And what, exactly, was his point with "even though they make less money than computer programmers, they have been able to convince higher level management that their work requires better hardware"?  That was even more condescending than his earlier remark about QA.  His overall lack of professionalism is superbly exemplified here.  Honestly, I can't even formulate a response to this part, so I'm just going to walk away.

But before I do, I'll draw one last bit of attention to the end of that paragraph.  Yes, the graphic arts department has convinced management to provide better hardware.  And, yes, when the author tries to do the same he is seen as a whining geek who just wants high-tech toys.  But, given his other statements in that paragraph and throughout his post in general, I'm inclined to believe that this has less to do with the fact that he's a programmer and more to do with the fact that he's an unprofessional whiner.  Management can smell that from a mile away.  If the sum total of his plea to management was nothing more than, "But they got new monitors!  I want a new monitor!  That's not fair!" then it's pretty plain to see why he didn't get his way.  As I said earlier, it's our job as professionals to communicate effectively.

So What's a Good Profession?

Here he closes his argument by telling people that they should just be accountants or lawyers instead.  I definitely don't follow the logic here.  It seems like he just trailed off and forgot to write an ending for his diatribe.  He reasons that one can only be a lawyer if one graduates from an ivy league school, and one can be happy as an accountant because one can still do that when one is fifty years old.  (Which again reiterates his notion that he doesn't plan to advance his career in any way after doing it for at least ten years.)

So, if someone is passionate about software, but doesn't see a lot of money in it, then one should just choose a career with more money even though one is not passionate about that profession?  Wrong.  Just plain wrong.  If one is passionate about those other fields, then they're certainly options.  But if one isn't inclined to care about those fields in the first place then how can one expect to excel in them?

Ultimately, I don't recommend taking career advice from someone who hates their job, doesn't have any ambition to excel in that job, is horrendously unprofessional, and believes that the mark of a good career choice is decided primarily by which kids were more popular in school.