Friday, November 30, 2007

Linq to Sql and Enums - Unexpected Behavior - Part 2

In my previous post, I mentioned the first set of unexpected behavior I ran into with Linq to Sql and Enums. Here's the next one:

So the Asp.net RoleProvider wants an array of strings the represents the names of all the Roles a given user is in. So here's the Linq code that I wrote to do that:

return (from u2r in lMainDataContext.User2Roles
where u2r.User.EmailAddress == username
select u2r.RoleTypeEnum.ToString()).ToArray();

The problem, the array that was returned contained the value "2".

Why, because Linq to Sql tries to convert this query to Sql and execute it using the database engine.

The problem is that RoleTypeEnum is an int as far as the database engine is concerned and so it returns a string representation of that int, instead of "Partner" which is what I was expecting.

Splitting the query into two forces Linq to Sql to map the int to an enum:

RoleType[] lMatchingRoles = (from u2r in lMainDataContext.User2Roles
where u2r.User.EmailAddress == username
select u2r.RoleTypeEnum).ToArray();

return lMatchingRoles.Select(r => r.ToString()).ToArray();

Another place where you realize that SQL Server doesn't really know about enums.

Linq to Sql and Enums - Unexpected Behavior - Part 1

It's been a long time since my first post. A lot has happened since then. The biggest change is that I quit my job almost 3 months ago and I'm now working full time on my very own startup. I'll blog more about that later. Anyhoo, this explains why I'm still up at 7:27 in the morning.

But I just ran into two sets of unexpected behavior using Linq to SQl and enums and I wanted to shared them with you.

So we have the following enum:

public enum RoleType
{
Admin = 1,
Partner = 2
}

which maps to a column in the db. We're using Linq to Sql's nifty Enum mapping capabilities that allow us to work with the enum in code while beneath the covers, it automatically translates between the enum in code to the int in the db.

Our db column looks like this:



Notice that the int that stores the enum value can't be null.

Of course, now Linq to Sql has a problem. The User2Role entity that this column belongs to has a property named RoleTypeEnum thats a non nullable int in the db but is a RoleType enum in code.

So when you create a new Role2Enum entity, the RoleTypeEnum defaults to 0. And if you don't replace that 0 before committing to the database, well guess what, the db wont complain because as far as it's concerned, the value of RoleTypeEnum is not null even though its an invalid RoleType of value 0.

More fun ensues when you try to get the invalid RoleType:

RoleType lRole = (from u2r in lMainDataContext.User2Roles
where u2r.User.EmailAddress == username
select u2r.RoleTypeEnum).Single();

The value of lRole is 0, which breaks all sorts of stuff.

This explains why when analyzing my code, the code analyzer suggests that I should add a new member None with value 0 to the RoleType enum.

Here's the next one

Sunday, May 20, 2007

I know Code Fu

How this blog was born....

May 20th, 2007 8:35 pm.

At my day job, I work as a software engineer creating games for the Xbox 360 and the POS 3, did I say POS, I meant PS3. Right now we are nearing the Alpha stage of the product, about to go Beta soon and what that basically means is that we have been working 12 – 14 hours a day, 6 days a week trying to get this game done and on the shelves. This is actually better than the last few cycles (years) because there have been times that I have gone to work at 10 in the morning and returned home at 10am the next day. Anywayz, the last few days I have been working exclusively on the PS3, basically wrestling with it, dealing with the GPU crashes etc trying to get a feature that just works on the Xenon (Xbox 360) working on the PS3. And it literally feels like I am fighting with that darn machine to get my job done. Yesterday I finally got it to do one part of what I was trying to accomplish and it felt like I had won a grueling deathmatch with the machine. There I am covered in sweat, but I can still feel the machine mocking me, “You may have won this battle, but you won’t win the war”. In fact, I had to have dinner again after I got back home at midnight last night since fighting with the PS3 was soo physically demanding.

Well in my spare time (or whats left of it right now), I also like to code various different things. Today afternoon, I had planned to start working on a code project that I have been thinking of for the last few days. But I think the last week of constant work took its toll on me and a short afternoon nap at 4pm turned into a 4 and a ½ hour sleep fest to get my energy back. Even as I start to write this now, its only been 10 minutes since I woke up. But anywayz, I woke up and the project I wanted to start was still on my brain and the first thing I thought on waking up was “It's time for some Code Fu”. No idea where that came from, I haven’t watched the Matrix (I know Kung Fu??) in a looong long time, but I think it’s just my subconscious describing the last few days of fighting with the PS3. Or maybe it’s my mind saying “enough sleeping, time for work” albeit more dramatically. Anywayz, the creative side of my brain heard what the other side had just said and was like “That would make a great blog title”. Still in bed I grabbed my UT Starcom VX6700 which has Verizon’s ultra cool broadband access and hit networksolutions.com to check if “codefu.com” was taken. It was, but “codefuTime.com” wasn’t, so I picked that name. I’ve always wanted to start a blog, but never had the time until I decided to just do it about 2 minutes ago. Strange how that works huh?