What am I missing with my Entity Framework? - asp.net-mvc

I have asp.net membership and I use the built in Create user method since it is convenient now after this depending on the user I want to add 2 more fields to the aspnet_UserTable.
In my aspnet_user Table I have like this
// All Standard Fields that come with this table
ClubID<nullable)
ClubName <nullable)
I have a table that relates this
Club Table
ClubID<PK>
ClubName
So this relationship forms that one club can have many users. But one user can only have 1 club.
So now I been trying to figure out how to add the ClubID to the aspnet Usertable since it does not show up in the Entity Framework Diagram since it does not show FK.
// Note in this case I am just using EF made to create but in reality I will use the Membership.Create.
aspnet_Users test = aspnet_Users.Createaspnet_Users(Guid.NewGuid(), Guid.NewGuid(), "myTest5", "mytest5", false, DateTime.Now);
test.Club = Club.CreateClub("One224", "Two224");
test.ClubName = "go";
MyEntities.AddToaspnet_Users(test);
MyrEntities.SaveChanges();
So what I have works but it just makes no sense and I hope there is a better way. Like I try to create the club and then stick it in the test.club.
This add's the ClubID primary key but does not add the clubName.
So then I have to add the club name separately. Like why? Is there not a better way?
I also prefer linq method syntax so if it is needed and you know this syntax can you please write it in that.

I would recommend a few things.
One: Strongly consider not adding columns to the aspnet_* tables. If you ever want to change your authentication method down the road you'll be stuck lugging those tables around with you even though you won't need them anymore. Also, there may be a new, better version of the membership provider one day that you won't be able to upgrade because you have customized the membership schema.
Two: Instead, why not create a new table called User (or something of your liking) that has your own primary key but links back to the ASP.NET Membership unique key (the guid).
Your table might look like
User
UserId (PK)
AuthenticationUserId (FK back to aspnet_User table)
ClubId (FK back to your club table)
Three: I don't understand why you've repeated ClubName both in your user table and in your Club table. You really only need to define the ClubName once, right? Keep your Club table how it is but remove the ClubName column from the user table.
Your code above for associating the club with the user is correct and works because that's how the Entity Framework works. You're associating entities with each other and are abstracted from some of the relational aspects of your data schema. It's a little strange to get used to it first but it does work.

Related

Entity framework multiple DbContext in single execution

I have one master & detail in my 'db1' and there is one column named 'EntryByUserId' in master table.
User table is available in 'db2'.
When all the tables are available in one single database we can directly get user detail by using include function. But here my reference table is in another database so in my case user object will return null value. So anyone please help me to achieve this.
I have created multiple dbcontext in my project but don't know how to get this.
Below is the code we use when all tables are available in single database.
dbcontext1.tbl_Master.Include(m => m.tbl_Detail).Include(m => m.tbl_user)
.AsNoTracking().FirstOrDefault();
One option to accommodate this cleanly, especially for something as frequently accessed as a "User" reference for something like reporting on CreatedBy or ModifiedBy tracking on rows would be to implement a view within Db2 that lists the users from Db1. Then in your main application context you can map a User entity to the view rather than a table. I would put guards in your DbContext and entities to discourage/prevent modifications to this User entity, and leave maintenance of users to a DbContext overseeing the Db1 tables.
If this is something like a multi-tenant system with a system database for authentication and separate DBs per tenant which are tracking things like CreatedBy against records, I would recommend considering a system to inspect and replicate users between the auth database and the respective tenant databases. The reason for this would be to help enforce referential integrity for the data and the user references. The issue with the view approach is that there is no constraint available to ensure that a UserId reference actually corresponds with a row in the Users table over in the other database. It can be indexed, but not constrained so you have to handle the possibility of invalid data.

MVC Database Model Dynamic Properties

He guys, so I need a little help with my database model for an mvc project I am working on.
Here is the situation:
I have a table called dbo.Clients that has the columns ClientName, PlanName, PlanPrice, PlanStartDate, PlanEndDate, and IsArchived.
For the fields ClientName, and IsArchived are only going to have one value in them that is subject to change. However, each client will have multiple PlanName, PlanPrice, PlanStartDate, and PlanEndDate values.
I have a ClientModel, ClientViewModel, ClientRepository, ClientService, and ClientController set up that successfully puts values into the database from the view.
The problem:
The way that I have done this is that I can only use one value for PlanName, PlanPrice, PlanStartDate, and PlanEndDate. For example lets say a client has bought Plan 1 and Plan 2 but I cannot store more than 1 plan.
What I want to do is make another table called Plans but I'm not quite sure how to use that in the MVC way to storing multiple values per client.
You need two tables. One will be a client master named something like Clients with the Columns Id, ClientName and IsArchived.
The other table will be something like ClientPlans with the columns ClientId, PlanName, PlanPrice, PlanStartDate, PlanEndDate
Ensure there's a Foreign Key relation between the Id in the Clients table and the ClientId in the ClientPlans table.
This can be refactored further to have a separate table for Plans (Id,PlanName, PlanPrice, PlanStartDate, PlanEndDate) and a transaction table called ClientPlans containing ClientId and PlanId with the appropriate relationships set.

Can I use the SimpleMembershipProvider with a different table to UserProfiles?

First of all, I only want one database, not an extra silly little thing for credentials. I have read that this provider uses the UserProfiles table to store login credentials. I would like to use my Occupant table, and not have to link the two. Is this possible, and how do I do it?
If it must be UserProfile, could I perhaps inherit Occupant from that using EF inheritence features, so the provider sees only a UserProfile interface on my Occupant table?
You can change the name of the table to use in the WebSecurity.InitializeDatabaseConnection method. There is a parameter in this method called userTableName. If you have a different name for the user name column in the Occupant table then you would also specify that in the parameter userNameColumn. Also the identification column name used in your table would be specified in userIdColumn. There are techniques for including the SimpleMembership database with your your own database and the details depend upon if you are using the code-first or database-first approach. Out of the box SimpleMembership is code-first.

How does the Rails' single table inheritance works?

I have a user table, and a teacher that I newly created. The teacher is sub class of user, so, I use scaffold generator to generate the teacher table, than, I modify the model to do teacher is subclass of user. After all that, I did a db:migrate. Then, I go to
http://localhost:3000/teachers/new
It shows an error:
undefined method `teacherSalary' for #<Teacher:0x103331900>
So, my question is what did I do wrong? I want to create a page for doing user register, the user can ONLY be a teacher / student. But I can't add a teacher record ... ... Moreover, I go to
http://localhost:3000/users/new
I want to have a combo box that allow user register their user to be a "teacher" or a "student". But everything seems not work like I expected. What I need to do? Thank you very very much for your help.
Within your database you should have a single table called users. This table should have a string column which by default is called type. If you use another name for this column then you will have to set the inheritance column name manually using self.inheritance_column = "column_name"
Within your application you have three models, User, Student and Teacher. User inherits from ActiveRecord::Base as usual, Student and Teacher both inherit from User.
You should then be able to instantiate new Teacher and Student objects. Internally this works by writing the model name to the type field on the user tables and then when you use Student.find it adds a clause to the SQL to only return rows where the type = 'Student'
You can add shared behaviour to the User class, e.g. validations etc then add additional behaviour to the inherited classes.
A fuller description of how STI works can be found in Martin Fowlers Book(Patterns of Enterprise Application Architecture).
I found this definition really handy:
STI means one table contains the data of more than one model, usually differentiated by the "type" column. ("users" table contains data for the models "Teacher", ""Pupil", "Employee", "Assistant", etc.)
Keeps similar models in the same table instead of creating new ones.
A Polymorphic Association means that one model can be associated with more than one other model(Comment can belong to post, image, file, user_type...)
To prevent foreign key conflicts, the association is reperesented with the *_id and *_type columns instead of only *_id.
For what you have here , I am not sure if STI is the best way go . STI should generally be used when there is a OO like inheritance and the Models have the same Attribute but different behaviour . In your case Teacher and Student can sure have a few shared attributed , but they are also bound to have different ones as well .
You might want to experiment with a polymorphic association as well .

How to get the foreign key in Entity Framework?

I am developing StudentApp in .NET 3.5 SP1 MVC Application.
I have two tables
Course
CourseID, course_Name
Students
studentID, student_Name, courseID(fk)
Now I made StudentApp.dbml which is having both table as entities.
As Foreign key will not be present in student entity,
I can not display courseID in student model, more over i can not generate add, edit, list views.
So tell me how to display courseID(fk) in student & i also want course name instead.
And also dropdownbox showing course name & storing courseID in edit view .
I'm pretty sure you have to load the foreign reference for each entity. Since I have no idea how you've constructed your API, I'll have to give you a pseudocode'ish example, but I think this is what you need to do.
List<Students> studList = [your_db_facade].SelectStudents() // Or however you retrieve your students
foreach (Students singleStudent in studList)
singleStudent.Context.CourseReference.Load() //CourseReference.Load() should be in the framework
Then you get the CourseID and name from the single student entity like
singleStudent.Course.CourseID
singleStudent.Course.course_Name
It could look slightly different for you, but I think the key to solving your problem is CourseReference.Load().
If your using LINQ-to-SQL and created a DBML file in Visual Studio then the foreign keys can be listed through the Course property in the Student object (automatically generated so since it is a one-to-many relationship from Student). Sort of like this:
var studentCourseIds =
from s in context.Students
select s.Course.CourseID;
Since your goal is to find the coursename then it is already accessible with Student.Course.course_Name.
Can you post your DBML? Also, DBML is used in LINQ to SQL (L2S) - EDMX is the mapping used in the ADO Entity Framework. Are you using LINQ to SQL or the Entity Framework (EF)?
No matter which one you are using - they both support Foreign Keys and you would get a property representing either side of the relationship - you don't need to do anything special (the Foreign Key must exist in the database, of course).
In EF, the foreign keys are called "navigtion properties" and they work a little differently to Foreign Keys in L2S. Nothing major, but updating them and "eager loading" are somewhat different.
Just drop the tables onto the map in the designer in Visual Studio (or generate using command line equivalents if you prefer).
Regarding Foreign Keys and Drop Down Lists (and other UI goodness) - I wrote a couple of blog entries on some approaches which might suit you. One part is located here and part two is located here.
if you create the correct relationship in your SQL server database, then when you add the tables to your DBML designer, the relationships will be copied across also and your code will link up automatically.

Resources