Merging two ASP.NET membership databases - asp.net

I have to merge two ASP.NET membership databases with related role and profile tables. Both databases have an identical role and profile structure. They use the built in providers (SqlMembershipProvider and friends). Duplicates are possible.
Do you have recommendations for me? Is there a tool to do this? If not: Can you recommend using the membership API or is it easier to use SQL.
Update
Here is the script I finally used to transfer the membership data.
insert into targetMembershipDatabase.dbo.aspnet_users
select * from sourceMembershipDatabase.dbo.aspnet_users
where username not in (select username from targetMembershipDatabase.dbo.aspnet_users)
insert into targetMembershipDatabase.dbo.aspnet_membership
select * from sourceMembershipDatabase.dbo.aspnet_membership
where userid in (select userid from targetMembershipDatabase.dbo.aspnet_users)
and not userid in (select userid from targetMembershipDatabase.dbo.aspnet_membership)
insert into targetMembershipDatabase.dbo.aspnet_profile
select * from sourceMembershipDatabase.dbo.aspnet_profile
where userid in (select userid from targetMembershipDatabase.dbo.aspnet_users)
and not userid in (select userid from targetMembershipDatabase.dbo.aspnet_profile)
insert into targetMembershipDatabase.dbo.aspnet_usersinroles
select * from sourceMembershipDatabase.dbo.aspnet_usersinroles
where userid in (select userid from targetMembershipDatabase.dbo.aspnet_users)
and not userid in (select userid from targetMembershipDatabase.dbo.aspnet_usersinroles)
Provided as is. No check for duplicate emails. No warranty that this is working in a more complex scenario.

I not aware of any tool which will do this, but the schema is pretty simple so it would be a straightforward enough job to just do it in SQL. All the keys are GUID anyway, so there shouldn't be a problem.
Obviously you'd need to check the user_name field for duplicates and email addresses, if the unique email address rule is applied. But if the roles are the same in both databases then all you're really interested in are the users. Once you've got them over it would just be a case of updating the RoleId and ApplicationId in aspnet_Users and aspnet_UsersInRoles.

I am currently use a single database for three different applications. Each of them has its own ApplicationID and nothing special happend for me withing this 2 years. even similar mails are available (because sql check the ApplicationID and in each application only you have one mail) so I don't think that you have to consider something special
Just create a script from data and run in your mainDatabase just not that don't replace the schema of Tables.

Related

How Get RoleID in ASP.NET MVC

Is there any way to get RoleId without get directly from DB?, I know we can get role Names by:
string[] allRoles = System.Web.Security.Roles.GetAllRoles();
string[] allRolesForUser = System.Web.Security.Roles.GetRolesForUser(httpContext.User.Identity.Name);
But I need to access roleId.
Does any one have any idea about it?
No. The role provider have no knowledge about the data source. It can be a very slow web service or a super deluxe NoSQL database. The provider doesn't know that your db as a primary key.
Sure. The SqlMembershipProvider does. But having it exposing the key would likely lead to violations against Liskovs Substitution Principle.
The role name should be unique. So you should yourself be able to fetch it from the database. Or why can`t you simply use the role name directly instead of the db key?
You must add aspnet_Roles table to your model and use query (for example LINQ) to get roleId .You can change MembershipProvider but it need more work for doing it.
You can't. ASP.NET MVC doesn't allow to get RoleId with standard functon, you must get it from database with the help of role name.
I realize this is a few years old, but when i bumped into it I saw that noone actually answers completely answers the question ...so I thought I would post a full solution.
Soooo...
Simply put:
SELECT RoleId, RoleName FROM aspnet_Roles;
GO
But for getting RoleIds for a User it is like this:
SELECT UR.RoleID, R.RoleName FROM
aspnet_Users U, aspnet_Roles R, aspnet_UsersInRoles UR
WHERE U.UserName = #Username
AND UR.UserId = U.UserId
AND UR.RoleID = R.RoleId
GO
This will give you a 2 column list of RoleIds and RoleNames for a particular user.
In reality, you should not be trying to do this as there is a potential for Security breach when a RoleId is exposed. You should only work with RoleNames and use the Membership and Roles methods to manage things.
Hope this helps :)

How can I restore selected ASP.NET Membership users from a backup DB?

Had a recent issue with my CMS and discovered today that all of my users created in the last week were deleted. The good news is that I have a backup of the DB, and that it uses standard ASP.NET Membership tables.
Is there a way to do a restore of this data without restoring the whole DB? The membership tables are something of a maze... is there an existing stored proc or utility out there? I'm not sure which tables would be required and which ones would not.
I'm not aware of any single sproc or utility to do this.
If you're using just the Membership, you'll need to copy from:
aspnet_Membership
aspnet_Users
If you're also using Roles you'll need to copy from:
aspnet_UsersInRoles
If you're also using Profile you'll need to copy from:
aspnet_Profile
So basically it's not that bad. You just need to roll up your sleeves and write between 2 and 4 insert statements. (that's the theory at least)
Follow-up to Greg's correct answer... here is the actual SQL script I used:
INSERT INTO aspnet_Users
SELECT * FROM Restored.dbo.aspnet_Users WHERE UserId NOT IN (SELECT UserId FROM aspnet_Users)
INSERT INTO aspnet_Membership
SELECT * FROM Restored.dbo.aspnet_Membership WHERE UserID NOT IN (SELECT UserID FROM aspnet_Membership)
INSERT INTO aspnet_Profile
SELECT * FROM Restored.dbo.aspnet_Profile WHERE UserID NOT IN (SELECT UserID FROM aspnet_Profile)
INSERT INTO aspnet_UsersInRoles
SELECT * FROM Restored.dbo.aspnet_UsersInRoles WHERE UserID NOT IN (SELECT UserID FROM aspnet_UsersInRoles)

ASP.NET SQL Membership Tables

What's the best way to tie my tables (like Customer, Orders) to the Users in the membership tables. Is there a way to tie it using an int somehow?
You can use the User.ProviderUserKey but that is a GUID, not an int. That will map to the UserId field in the aspnet_Membership table

LINQ to SQL for tables across databases. Or View?

I have a Message table and a User table. Both are in separate databases. There is a userID in the Message table that is used to join to the User table to find things like userName.
How can I create this in LINQ to SQL? I can't seem to do a cross database join.
Should I create a View in the database and use that instead? Will that work? What will happen to CRUD against it? E.g. if I delete a message - surely it won't delete the user? I'd imagine it would throw an error.
What to do? I can't move the tables into the same database!
A view will work, if you have granted access to both database to the configured user. You'll need to use the 2-dot notation. This will only work BTW if both databases are on the same server.
create view vwUserMessages as
select * from db1.dbo.Users as users
inner join db2.dbo.Messages as msg on msg.UserID = users.id
For CRUD: a view is (usualy) only for reading: do updates etc directly to the related tables, or use a stored procedure:
create proc pdeleteUserMessages (#UserID int) as
begin trans
delete db2.dbo.Messages where userid = #UserID
delete db1.dbo.Users where id = #UserID
commit trans
go

Best database design approach to join complex data to ASP.Net Membership tables

I'm looking to use a slightly modified ASP.Net Membership Provider to handle the standard user account creation/authentication/etc in a website. We have a fair amount of legacy data that I need to migrate in order to provide continuity with our existing users' saved information (like order history, wishlist, etc). [NOTE: We have to migrate anyway, so this is not the reason we're migrating data]
I'm wondering what a sensible approach is for joining this additional data to the asp.net membership tables. There are a two unique keys that I could use on the user table - UserId or email - which we will use as a surrogate for username.
My question is, what is the better access pattern (and hence foreign key) to use elsewhere in my tables for storing orders, wishlists, etc?
In HttpContext, a User object is available that contains the "Username", our email address,
but doesn't have the Guid for userId available.
I see 3 options:
I'd like to simply use the uniqueidentifier UserId for efficiency of access over a lengthy varchar email address, but it doesn't appear readily available without extra database calls to fetch it via email/login. Is there some way to get the UserId so I can make it the foreign key on different tables?
I can pass in email address (username) as the input parameter, join on userId where email address = #emailAddress, and use userId as the foreign key on other tables.
Not viable
I can store username/email address on all the other tables as a foreign key - which would be an unfortunate denormalization
Any thoughts on a best method from either a DB perspective or from an application efficiency perspective?
You can get UserId:
MembershipUser myObject = Membership.GetUser();
string UserID = myObject.ProviderUserKey.ToString();
or maybe (please, check it)
string userId = Membership.GetUser(User.Identity.Name).ProviderUserKey.ToString();

Resources