views:

130

answers:

5

This is my first MVC/Linq to SQL Application. I'm using the out of the box SQL Membership with ASP.NET to track users through my system.

As most of you know, the UserId is a guid, great. However, to link other user-created tables in the system, I decided to go with username instead of userid. The reason I did this was because:

  1. Username is unique anyway
  2. It prevents me from having to make an extra call when handling db functions.

So for example: I don't have to do a look up on the userid based on username to create a new story; I simply insert User.Identity.Name into the story table.

Now I did run into some nasty complication, which seems to be related to this. It worked fine on my local machine, but not on the host. I continually got an error that went something like this:

"System.InvalidCastException: Specified cast is not valid. at System.Data.Linq.IdentityManager.StandardIdentityManager.SingleKeyManager"...

This happened whenever an insert on the db occurred on the host. If I understand correctly, this is a bug currently that happens when you link a non integer field (in my case username) to another table of a non integer field (username in aspnet_user). Although the bug reported seems a little bit different, maybe they are similar?

https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=351358

In any case, MS bug or not - is storing the username instead of the userid in my tables a bad idea? If it is, why?

Update

I just wanted to add some more context here. A good point people are bringing up is that this is dangerous if I want to allow users to change their username in the future. Perfectly valid!

However, this application relies heavily on the username. Each user creates one and only one story. They then link to their story by using: mysite/username. Therefore, the application will never allow them to change their username. It would cause a potential nightmare for people who follow the link only to see it no longer exists.

+1  A: 

I've used the same approach as you and it works. Do you have a relationship between your application table and the table from the membership db? If so, you may want to remove that relationship.

Good to know I'm not the only one. No link exists today.
Beavis
Just to clarify - because of the bug I no longer have a relationship with my created tables and the aspnet_user table. Makes me a little uneasy but I don't think it should be a problem.
Beavis
+1  A: 

My only thought would be in order to future proof your application, the userid would offer flexibility in users changing their username, as the userid would remain constant (like SO for instance). But that is something that has to fit your application requirements. Then again requirements often tend to change wihtout a developers control.

Jakub
Excellent point you just made! For my application the username will never change. Thanks.
Beavis
+1  A: 

Be careful regarding your comment regarding usernames are unique. The minute Anita Takeabath gets married to Seymour Butts suddenly atakebath wants to be abutts.

Just a thought!

JonH
Yes, excellent - along the lines(but slightly more interesting way of putting it) of what @Jakub said.
Beavis
A: 

It's bad for the following reasons:

  1. You mentioned avoiding extra database calls. However, by joining tables, there is no "extra" call to database. You can argue that joining is expensive than no joining at all. However, most likely, a store needs more user information than a user login name (note: user names are not unique, user login names are unique). So you need joining anyway for most database operations.

  2. User login names have different length, it doesn't perform well when they are used in joining.

Edit: modified format. I am still learning how to make my post look better:-)

Codism
I'm talking User login names, so they will be unique. Now on your point of joining - that's true for selects, but what about inserting? So I create a new story, new comment, etc. Wouldn't I have to first get the userid from the username and then insert? That's what I'm trying to avoid.
Beavis
I usually don't like to ask this question but I have to ask now: why are you trying to avoid it? Insertion would be significantly less than selection in most cases. So performance should not be a concern here. If not the performance, what else are you trying to avoid? I feel you are trading something trivial with a serious price.
Codism
I guess I'm just taking the slightly easier, less bullet proof way because the applications usernames are 100% unique. I just can't think of any downside to it right now...
Beavis
fyi - I added a bit more context to my original post.
Beavis
A slightly easier way would be once a user passed authentication, keep the id in session and use it whenever needed.
Codism
After further thought I'm going to take the safe road and make the userid the key. Thanks.
Beavis
A: 

If the reason you're implementing this is for easier access to the User's GUID, I suggest having your FormsAuthentication.SetAuthCookie use the users's GUID as the name property and use User.Identity.Name throughout your application.

Using username as the unique identifier could have bad consequences in the future. Should you want to allow the user change their username in the future, you will have a hard time implementing that.

Baddie