There are two entities in my app: Class and Student, they are many-to-many relationship, like following:
My problem is that in my app, there are two status of student in a class: pass and fail. I don't know how to model it to class or student. For example, should I make another Entity to express the status of a student? Or just adding a status attribute to Class entity?
Presumably you can't add an attribute to class because then if 20 students are taking the same class there'll be only one attribute between them?
You'll need to add a separate entity which has a to-one relationship with both a class and a student and which contains the status. And in reciprocal both student and class will have a to-many relationship with statuses.
EDIT: I guess an alternative solution would be to insert the status directly in between your existing relationship. So a class has a set of statuses, and each status has a student.
So relationships would be one to many from class to statuses and many to one from statuses to students. There'd be no explicit relationship between class and student.
I would suggest having a third entity which expresses the status for the student in a specific class. For example a Set of "classStatuses". Since you might need to store other information later, for example grades, credits, assistance records, etc etc.
The final scheme would be something like
Class - Student in a many to many relation.
Student - ClassStatus in a one to many. (Picture is as an array of the classes the student is taking with its respective status)
This way you can search for the students in a class, search for the classes a student is taking, check the status of the class.
Related
I have been using Core Data to model my database. I have 2 entities that are in many to many relationship. Each person can have many addresses, and on each address multiple persons can live.
Now i would like to add property to this relationship. For example one person - address will have label home, other person - address can will have label mama's place.
I can't add this property on address entity, because same address will have different labels for different persons.
Since relationships are modeled like NSSets, I don't see a way to do what I want.
Can this be somehow done?
It is not possible to add attributes to a many-many relationship directly. The Apple-recommended approach (see "Modelling a relationship based on its semantics" in the CoreData Programming Guide) is to replace the many-many relationship with an intermediate entity, to which you add the attributes. Each of your existing entities will have a one-many relationship with the new entity.
In your case, you might have something like this:
Person <--->> PersonAddressDetails <<---> Address
You can then add the label attribute to the PersonAddressDetails entity.
I will preface it by saying I'm a database person, moving into .NET, MVC, EF etc. So I fully understand about joins and foreign keys and so on but I am struggling with the EF side.
I worked through a tutorial where we did the following:
create a Student table (StudentID and personal details), a Course table (CourseID and subject details), and an Enrollment table (EnrollmentID, student and course IDs and the grade given to that student for that class).
create Models, Controllers and Views for Student and Enrollment entities to allow editing the name of a Student, enrolling a student for a class and giving them a grade, list out all enrollments, etc.
In that tutorial the Enrollments table is (what I know as) a "bridge" table because student to class is a many-to-many relationship.
So do I only need this "intermediate" model/view/controller if it's a many-to-many scenario like this?
The actual structure I want to program is:
Article (ArticleID, title, author, summary, content...) is a member of a
Category (CategoryID, title, description, ...)
Then I want to have a drop down list (or whatever UI element) of Categories of which clicking on the selected Category will give a page with a table of Title/Author/Summary of the articles that go in that category.
If an Article can be in more than one category ("Effective Use of Catnip" could be under both "Playing Games with Cats" and "Life Hacks") is that where I would need a 'bridge' table?
Please can someone explain in simple terms - whether I am just being put off by the "many to many" nature of the data in that tutorial, or if the 'bridge' table structure is more fundamental to EF for navigating a PK/FK relationship.
I think the tutorial you are reading is trying to introduce you to the basic concepts of EF. If you have a many-to-many relationship, on database side you will always have three tables:
Student
Course
Enrollment (Student_Id, Course_Id)
On EF world, you can represent those three tables as three different entities. However, if you want to have a more "natural" way of representing the relation between Students and Courses, EF allows you to declare many-to-many as two lists:
public class Student {
... properties
virtual List<Course> Courses;
}
public class Course {
... properties
virtual List<Student> Students;
}
However, you need to instruct EF how this references on both side needs to be treated. For that, you can use fluent API. With this fluent API you can define the table name that references both tables/entities:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Student>()
.HasMany<Course>(s => s.Courses)
.WithMany(c => c.Students)
.Map(cs =>
{
cs.MapLeftKey("StudentRefId");
cs.MapRightKey("CourseRefId");
cs.ToTable("StudentCourse");
});
}
Check this article explaining the M:N relationship using fluent library API. Is really simple, and with that you don't need this additional element on the middle.
In terms of UI, you just need to select the list of courses the student want to take, or the list of students the course has to have. Is up to you how you want to present the information to the user, as both functionalities (students taking courses and courses defining its students) point to the same m:n relation.
I think a simple way can be to show a </select> list with the students, and then show the list of courses he can apply to.
The project you want to create uses the same ideas. Basically, with EF you will always need to think in terms of "tables". It is true that EF allows you to abstract your tables to entities, but still you need to follow some rules. To sum up: you are right. The "bridge" table is where you need to store the many-to-many relationships.
I'm a bit confused on what a many to many relationship is. I'm wondering if the following is a many to many relationship:
A student at a school has many clubs. A club at a school has many students. Let's say that the student has many attributes: firstname, lastname, phone, age, email, etc. A club only has one attribute: a name.
When I make a new club, I want to be able to give the club a name and one or more students. Upon making the club, I want that club to be associated with those students and those students to be associated with that club.
When I make a new student, I want to be able to give the student a firstname, last name, etc, and one or more clubs. Upon making the student, I want that student to be associated with those clubs and those clubs to be associated with that student.
I also want to display a club's students and a student's clubs on their show pages.
I've read that a many to many relationship is when you have a join table that lets you access common attributes of the resulting students and clubs, but there are no common attributes in my case.
Do I have a many to many relationship here? If so, do I use a HABTM or has_many, through relationship?
Actually yes you DO have common attributes.
You stated yourself that a Student has many Clubs
And a Club has many Students.
What is in common? Students and Clubs.
What now follows is to define what a Student and a Club actually are, which you already did.
A Student is a combination of firstname, last name, etc... What you have not specified is what makes a Student UNIQUE. A club also must be defined as to what will make it UNIQUE. While for academic purposes, you could say the name is what makes it unique, in real live, that would probably not be the best solution.
Usually for performance purposes, each student is given a unique Autoincrement ID (which is a number).
Same thing can be done with the Club.
You create a 3rd table which is what creates the Many to Many relation.
In that 3rd table, you have 2 columns. One with the Unique Index for the Student, and the other column with the Unique Index for the Club. You simply add an entry on that table in which you wish to relate a student to a club.
Since you can have many students assigned to the same club, and you can have many clubs assigned to the same student, you have a many to many relation.
Edit: As mentioned in another answer, your 3rd table should also declare the combined indexes as unique, so that you don't add the same entry multiple times.
You have a many to many
Create an id for each table that is unique for that table typically an auto incrementing int.
Then a third table that is a junction/intersect table call it X.
Put a row in X with the student id and club id if the student has the club and vice versa. It would have a unique composite key in table X across both id's in it.
The composite would guarantee no duplicate rows in X
Yes indeed there is a many-to-many relationship here, use HABTM. Also, why do you say that there are no attributes in common? Club names and student names are definitely common attributes in this case.
A design question which I need help with. It's best described with an example.
Using the following Domain models:
- Student
- Enrollment
- Course
Where Student and Course have a many to many relationship to each other, achieved by the Enrollment table, i.e. Enrollment has a StudentID (FK) and CourseID (FK).
Both the Student and Course classes each have a Navigation Property, i.e. an ICollection of the other.
I'm using View models, and would like simple CRUD functionality, to add, edit, delete students and courses. The View models are very similar to their associated Domain models.
To display the student's details is simple enough, but when it comes to displaying the student's course details, which of the below designs would be the best approach?
In the Student View model, declare an ICollection of the Enrollment Domain Model?
Then in the view the enrollment details are accessible.
I feel as if this undoes what the View model is trying to achieve, and that is to have an abstraction layer from the domain model. Using this design, the Enrollment Domain model is accessible from the View, via the Student View Model.
Create a View model for the Enrollment class.
This will be identical to it's Domain model. Doesn't do anything else other that hold the Domain model's values from the View Model. Has to be mapped via AutoMapper. Not sure what to make of this option, feel's inefficient.
First of all, Enrollment should not be a domain model. Enrollment is just a database table which specifies a many-to-many relationship from Students to Courses.
My suggestion is to create a List of Courses in the Student domain model, and use NHibernate or Fluent NHibernate to map the Student and Course, then create a many-to-many relationship from the mapping, and you can simply retrieve the Courses from a Student instance.
Also, you can use cascading operations more freely when using a mapping instead of writing some SQL statements in your code.
Consider this simple application in RUby on Rails:
Student & Teacher extends Person.
Person has 2 properties, name & age.
Student has 1 extra property, grade.
Teacher has 1 extra property, salary.
I want to store the student & teacher information in separate db tables. I want to take advantage of RoR's utility class ActiveRecord:Base to retrive data for these models. Because Person is not expected to be instantiated, I can mix it with Student & Teacher as follows:
class Student < ActiveRecord:Base
include Person
end
module Person
end
Question:
Is this the correct way of implementation?
How to implement this without creating a databse table called persons? I only want to generate 2 tables, namely students and teachers, and both should have the 3 properties mentioned above.
Person does not have to be a model - it can be a library/module (which you then mixin as per your example). You'd keep that in RAILS_ROOT/lib.
Your Student and Teacher classes can be models (which use AR::Base), and the person can just be a bunch of common methods used by both.
Alternatively, if your child class is far more complicated - look into "Single table inheritance" - the description of which is beyond the scope of this answer... but you can google for it.