views:

38

answers:

4

I want to do something like SO does with DisplayName. When someone does not enter a DisplayName, I want to default this to 'User' + UserId. So the first user who signs up would get User1 - since UserId will be 1, the second User2 - since UserId will be 2, and so on.

The easiest way I can think of doing this is using a trigger, but I don't like triggers. I could save the user, then update the user after the save (basically a trigger, but done in my code). Any other ideas on how I can handle this? Is there a way I can set the default value on the column in the database?

I am using Asp.Net MVC 2, C# 4, EF4, and SQL Server 2008.

+3  A: 

You can set the user name in the stored procedure. if a user name has been passed to stored procedure, simply save it. otherwise, get the primary key id of the last entered user and add 1 to it. format it to whatever you like (e.g. User + newID) and save this as the new user's user name.

Kamyar
The only reason I am weary of this is because what if something went wrong, and the next userId is 4, but the last user is 3. Then it does not match up.
Martin
@Martin: select the MAX primary key. wrap the sp call it in a transaction in code behind. I think you're good to go.
Kamyar
@martin: if you're using default asp.net membership provider, I have made a post at http://forums.asp.net/p/1417444/3130659.aspx#3130659?Re%3a+Assign+Username+Programmatically that can help you.
Kamyar
@Martin - Is the UserId an identity column? If so, you can get the last inserted value using SCOPE_IDENTITY, right? why would it not match?
InSane
@InSane, it would, but I didn't want to get the max(UserId), then set the DisplayName, then Save, because I didn't think it would match, but if I wrap in a Transaction, I would be all set.
Martin
@Martin - I am afraid i dont quite get why you would need to do a MAX(UserId) or use a transaction. SCOPE_IDENTITY would return you the identity value inserted only in that very scope i.e the identity of the 1st insert statement. Hence there should be no need for max(userId). Also, If you are using the scope_identity value in the update for username, then i dont see any real need for even a transaction. Do you?
InSane
A: 

You can have a computedColumn

[UserName] AS ('User' + CAST(UserID AS VARCHAR)) PERSISTED
anivas
How would this work if someone actually passed in a UserName? Could I overwrite it?
Martin
You cannot update or insert computed columns, but you can have a UDF to decide the value of computed column. Write a UDF that takes a string and decides the user name.
anivas
+3  A: 
Select Coalesce(DisplayName, 'User' + Cast(UserID as varchar)) as UserName
pinkfloydx33
DUH! Thanks. This made me realize that this is business logic, so it belongs in my BL. I can change the get code on my DisplayName to do this.
Martin
No problem. No sense storing the extra field since the data (userid and displayname) are already being stored. Though I suppose that depending on the size of your table it may be more efficient to use isnull() instead of Coalesce as there are definite performance issues with Coalesce as tables/queries get larger.
pinkfloydx33
A: 

I would be inclined to generate it before saving to the database. No input = make one up.

I also would not have user User1, User2, ... but user+random: user6238945, user9287561, user8934678, etc

If you use 1, 2, 3, 4 etc then you are exposing an internal sequence. If someone gets "user4" then I know other users 1 to 3 exist, as well as number 5. This exposure was used many years by AOL or Compuserve (?) for phishing attacks.

gbn
But I am going to have something like SO, like: `http://site.com/users/144496/`, so you can get the userId, so I am not too concerned about the sequence. I guess the only thing I would be worried about is the fact that people can see when they sign up that they are only the Nth user.
Martin