views:

629

answers:

1

I'm trying to design an entity model for an application that uses ASP.Net membership for it's user authentication. In most of the database schemas I create, records typically end up related to users via the UserId field on the aspnet_users table. That's worked fine for me in the past, but now that I'm using EF, I'm having some conceptual issues with figuring out how I'm going to reference the user from an entity.

For example, let's say we have a "post" entity that contains a "postedBy" property. I'd LIKE to be able to do get the username of the user that created this post with something like post.user.username, but I'm wary of creating an entity based on the aspnet_user table for fear of creating a model that let's me bypass the Membership class when making changes to the database.

I've considered just leaving the post.userId field as a guid and then requiring that any code that needs to know the username use that guid to get the user from the Membership class, but that seems "ineligant".

Does anyone have any recommendations for entity model designs that integrate with Membership? I'd be reasonably happen with a "read-only" user entity.

+2  A: 

My advice is: "Don't."

Let me be more specific.

Using UserId as a mapped, foreign key ties your entity model not to ASP.NET Membership in general, but to the SQL Membership Provider in general. What happens if you then want to use domain authentication or OpenID?

Don't get me wrong: 99.9% of the time it's correct to tie DB references together with a foreign key. Heck, you could even do it here, but don't map it into your entity model. You need to keep a wall of logical separation between membership providers and your own data. You access your data through the EF. You access membership data through the membership API. The fact that they happen to live in the same DB because you happen to be using the SQL membership provider is an implementation detail.

Update: I've expanded upon this idea in a blog post.

Craig Stuntz
So, if you have "user" reference columns (like the postedby) in your data table, you suggest that it is mapped to a separate user table (as there should be no link between provider tables and appdata tables) ? So your database holds 2 separate user tables that must then be synchronized (i.e. by triggers) ?If not, could you explain how you do that ? I have the same problem here but I don't need to be able to change provider (it won't happen...).
Julien N
We don't synchronize, exactly. We have a SystemUser table which isn't strictly related to aspNet_Users. E.g., unregistering from ASP.NET membership doesn't remove the SystemUser record. We want to keep that around so that the "CreatedBy" fields on other records can still point at something. So we've customized the AccountController to update both membership and our own table when users are added or removed.
Craig Stuntz
Okay thanks. I forgot about the risk of losing the references. Your implementation seems a good one to me.
Julien N