Entity Framework One-to-one or zero - Database first - asp.net

I'm trying to create a setup where I have different entities (e.g. User and Customer). Each of these entities have some Login-information which I store in a Login-table to avoid having to do duplicate work on the different entities requiring Login-data.
However - I can't get the setup to work using Entity Framework. I hope you can help me out :)
My database has 3 tables:
Users
Id (PK)
Name
...
Login_Id (FK to Login.Id)
Customers
Id (PK)
CustomerNumber
...
Login_Id (FK to Login.Id)
Logins
Id (PK)
Username
Password
...
Each entity has one - and only one - login. So a given User has one Login. And a given Customer has one Login.
I need to be able to do something like this in C#:
var user = _userService.GetUser(2);
user.Login.Username;
var customer = _customerService.GetCustomer("abc");
customer.Login.Username;
But I simply cannot get the EF mappings to work.
I've tried changing my database schema so that Logins contains nullable User_Id and Customer_Id columns - but the result is the same. My Login-entity is null when accessing User or Customer. And I've already added the
Include(i => i.Login);
I might have just gone totally blind looking at it. I've read dusins of posts about this - but the majority of them seems to focus on Code-First and not Db-First (e.g. http://blog.bennymichielsen.be/2011/06/02/entity-framework-4-1-one-to-one-mapping/)
Could someone please supply me with the EF Fluent API mappings to get this to work?
Thank you guys so much! :)

Related

Asp.net Multi Tenancy implementation on existing solution

I have an asp.net MVC solution, Entity Framework code first, which has dozens of database tables all designed around a single company using the solution.
The requirement has come up to allow multiple companies to use the solution, so what we have done is add "CompanyID" as a column to all database tables and set a default value. There is a company table with the various company names and CompanyID's. On login the user selects the company they are logging in as which stores the CompanyID in the session.
At the moment every Entity Framework call now has to be updated to include the CompanyID, for example when selecting Employees I am doing:
List<Employee> employees = db.Employees.Where(x => x.CompanyID = Session.CompanyID).ToList();
As you can see it will be tedious to do this on thousands of calls to the db. Any update, save, and fetch has to change.
Surely I am doing it the long way and there is a way at runtime, globally to append all DB calls to include the CompanyID stored in the logged in users Session? Something that dynamically appends the CompanyID when fetching values or storing etc? Perhaps a package I can use to do this task at runtime?
In my opinion, there is no need to add CompanyID to EVERY table in the database. I would select just "root" tables/entities for that. For example, Employee or Department clearly sounds like a many-to-one relationship with a company - so adding CompanyID there sounds right. But, for example, EmployeeEquipment which is a many-to-one relationship with Employee does not have to have CompanyID column since it can be filtered by the joined Employee table.
Regarding your request to filter by CompanyID globally, I'm not aware of anything that can do that per request. There are global filters for Entity Framework, but I'm not sure how you can apply them per-request. Take a look on .HasQueryFilter() during model creation if you are using Entity Framework Core.

Using composite key in AspNetUsers table in MVC 5 application

I'm purposely not posting any code here as I'm really just looking for some guidance to the following problem:
I have created a three new fields in my AspNetUsers table - FirstName, LastName, and NickName. I also created a composite key using those three fields. When I try to create a new user that has all three of these fields the same, the application throws an error as expected when the unique rule is violated.
I would like it to simply post back to the Register User form indicating that the NickName must be changed to something else.
Do I need to implement a Custom User Store? Is there a simpler way?
Thank you for any suggestions.

performance issues in ASP.NET Membership

I am working with Aspnet membership, and I have stored users information in membership related data e.g. userid and password stored in Aspnet_Membership table, member profile like firstname, lastname, surname, dob etc in aspnet_profile table.
Now I need to add a search panel in my webpage. This search panel contains searching parameters like firstname, lastname and joining date etc. as per this searching parameters I need to search users from profile and user's last login information. I used profilecommon and profilebase class for retrieving this data. But it is seriously slow. The system takes at least 2 minutes to find data as per parameters from 70 records.
Please help to resolve this program.
You should retrieve the membership and profile information within the stored procedure, and not using any of the code-based classes to get the name. It won't perform well with extracting profile information per user.

aspnet_user table for storing customer information

When regsitering in my site (ASP.Net MVC application), the users get inserted into the aspnet_users table. Since its a shopping site, I would want the users to have a customer id and all their details provided by them at registration in this Customer table as well. How do I link these 2 tables? Is it recommended to use the aspnet_user's UserId(Guid) in the application for other business processes.
Also, I would like to know when should a new record be inserted into the customers table.
I mean, when should a new customer be created. I guess its not good to create a record as ans when users are registered? Here, I want to know whats the norm? I felt it would be better to add it when a user adds an item to the shopping cart. Pls guide me.
Thanks in advance.
Add the UserId field into your customer table and then make a foreign key relationship back to the UserId in the aspnet_users table if you want to enforce relational integrity.
I'm not sure what you mean about when to insert the customer record. As long as you insert it after you have created the user (so that you have the user ID), you should be fine. It can happen in the same postback.
I'm not sure how you are saving the user. As in are you using one of the built-in ASP.Net controls or making the call manually?
If you are using the Membership provider as it sounds like you are, you can save the member using:
var user = Membership.CreateUser;
Guid userKey = user.ProviderUserKey;
//Populate your customer object.
//now use whatever EF/ADO/etc... to save your customer record.

get current logged in userID in aspnet mvc membership

i am trying to show a list of users of my application "school", when admin logs in then he can view all the users in list but when school principals logins, he should get only users of his school, So i thought to get the current loggedIn userId first and then by that userId i'll get schoolId since userId is foreign key in school table...once i'll get the schoolId i can show the members of that school.
But my problem is how to get the UserID of currently loggedIn. I'm using MVC 1.0 Asp.Net -- "Membership"
if my logic above is wrong then please tell me the alternate good idea, so that principal can see only his users list..
Based on this question and answer by J. Pablo Fernández you can get the user id of the current user with the following code:
//It will only be a Guid if you are using SQL Server as the DB as oppose to MySQL
Guid userGuid = (Guid)Membership.GetUser().ProviderUserKey;
Here is the MSDN Documentation.
The Simple Solution
With the scenario you describe you would only be able to do this by retrieving the User information with the data stored in the HttpContext.Current.Identity. For example, if the HttpContext.Current.Identity.Name is the Username, then you would use that value to retrieve the User data for the principal that should include the UserId you can use to locate the appropriate school.
Alternate Solution
You might consider storing the SchoolId in the user's profile so that it is more easily accessible.
The easiest way that I've tried
You have to include Microsoft.AspNet.Identity
using Microsoft.AspNet.Identity;
Then use it like this
var userId = User.Identity.GetUserId().ToString();

Resources