1

In Entity Framework Core, while creating OTM relationship we basically pass the reference of one model into another like in below example

Student model:

public class Student 
{
    public int std_id { get; set; } 
    public string std_name { get; set; } 
    public int std_age { get; set; } 
    public int dept_id { get; set; } 
    public Department dept { get; set; } 
}

Department model:

public class Department 
{
    public int dept_id { get; set; } 
    public int dept_name { get; set; } 
    public int dept_capacity { get; set; } 
    public int std_id { get; set; } 

    public ICollection<Student> students { get; set; } 
}

But when we'll add a department, why do we need to pass the students, can't we pass the std_id directly?

Also, when we'll add a Student, we'll have to provide the department details as well, but can't we just pass the dept_id even though the department details will not be saved as well?

So what's the use of reference here? How do I add students and departments?

I'm able to save the department and student but if I add a student then it doesn't save the department details as we have given the reference here, same is happening with Department.

Attaching the screenshot of my Models, Controller, and UI

enter image description here

Alcoholic
  • 30
  • 1
  • 7
  • 1
    Please show us your code which is actually not working as you would expect. – Lukasz Mk May 23 '23 at 19:19
  • 1
    Are you sure this is one to one relationship? Seems like it's one to many relationships – Fitri Halim May 24 '23 at 04:25
  • 1
    @FitriHalim Yes it's One to many I've updated the question, please check once and let me know if you can help me out to understand it. – Alcoholic May 24 '23 at 20:10
  • 1
    What is `Department.std_id` intended to represent? It seems odd for a department to have a *single* value for what I'd expect to be a student ID... (As an aside, I'd strongly encourage you to follow .NET naming conventions in your classes, using attributes to specify column names if you need to.) – Jon Skeet May 24 '23 at 20:19
  • @LukaszMk I want to Add Departments, A department can have multiple students as I've written in Department Model, But in Swagger, While adding a New Department, it'll ask to enter the Student details as well, but when we'll save it only the department details will be saved, then why we are creating ICollection std{get; set;}, I just want to understand why we create a reference like this, and how I'll pass the data from the API UI? – Alcoholic May 24 '23 at 20:25
  • I just updated the question and added the screenshot, please check and let me know what I'm doing wrong – Alcoholic May 24 '23 at 20:33
  • You are not calling `Savechanges();`. – AVTUNEY May 24 '23 at 20:38
  • I know that's not the issue, I just want to know what's the use of ICollection in the department model cause while I Added migration, no column for student was created in department table – Alcoholic May 24 '23 at 20:41
  • [Please don't post code, exceptions, or results as images](https://meta.stackoverflow.com/questions/285551). They can't be copied (partly) for answering and their "text" won't appear in search engines. – Gert Arnold May 25 '23 at 07:22
  • Ok Gert, thanks for the suggestion, will take care of it next time – Alcoholic May 25 '23 at 18:57

2 Answers2

3

Usually the Department table is a master table. When you add student to the db, you just provide the department id and save the data in the Students table.

public class Student 
{
     public int std_id { get; set; } 
     public string std_name { get; set; } 
     public int std_age { get; set; } 
     [ForeignKey("Department")]
     public int dept_id { get; set; } 
     public Department dept { get; set; } 
}
    
public class Department 
{
    public int dept_id { get; set; } 
    public int dept_name { get; set; } 
    public int dept_capacity { get; set; } 
}

If you want to save the department details in department table, when you save the student details, you can use cascade insert. Here is the stackoverflow link of the same Cascade Insert in EF

Ajay Managaon
  • 450
  • 2
  • 9
  • 1
    Basically, what I want is, I want to add a Department and while getting the department, display all the students assigned to this department. I can do it by passing one student reference in department and then add the id, but in most of the tutorials, they create an ICollection Student {get; set;} this way, while adding a department we'll have to pass the student details as well even though only the student id will be saved then why do we create an ICollection and pass the all Student details? – Alcoholic May 24 '23 at 20:08
  • I just updated the question and added the screenshot, please check and let me know what I'm doing wrong – Alcoholic May 24 '23 at 20:33
  • 2
    We add ICollection because, we want to tell ef core that it should add a Fireign Key reference to Student table/class and not any other. If you have two Student table, for example MaleStudents and FemleStudents with "student_id" property? if you don't mention ICollection how will the ef know which table to add foreign key reference for? – Ajay Managaon May 25 '23 at 12:37
  • Hi @Ajay, thank you for clearing this doubt, It's really a good explanation. – Alcoholic May 25 '23 at 19:10
1

I think I understand your problem now.

I know that's not the issue, I just want to know what's the use of ICollection in the department model cause while I Added migration, no column for student was created in department table

Student column should not be added to the department table, else if we have many students, how many students column you want to add to Department table?

Rather we add an dept_id column in the Student table, so each Student know what is their department.

Basically, what I want is, I want to add a Department and while getting the department, display all the students assigned to this department.

When retrieving the Department and you want the public ICollection<Student> students { get; set; } property to be populated,

you can retrieve it like this

return await abd.Departments.Include(d => d.students).ToListAsync();

That's it.

And please modify your model by removing std_id from Department model.

Fitri Halim
  • 584
  • 4
  • 11
  • Hey Fitri, I'm familiar with this concept, we can solve the issue as you explained also I was doing the same, Please, can you confirm? when do we need to use ICollectoion as I said, we can solve the problem by the above way, but then why do most of the guys use ICollection in one to many relationships? – Alcoholic May 25 '23 at 06:02
  • 1
    Please read [Object–relational impedance mismatch](https://en.wikipedia.org/wiki/Object%E2%80%93relational_impedance_mismatch) which explains why elements of a collection as objects have a foreign key in the database, while parents in a relational database don't have any reference to their children. – Gert Arnold May 25 '23 at 07:28
  • 1
    Hi @Alcoholic, it is because one Department can have many Students, so to define this relationship you must define a property in Department that contain many Students. This can be `ICollection` , `IList` , `List` or perhaps if you are more familiar with C++ and C, you can also define the property as `public Student[] { get; set; }` as well – Fitri Halim May 25 '23 at 07:36
  • Hey @FitriHalim, thanks for this great explanation, just have one last question, as I created a Department model & it has ICollection or IList of a Student model, Considering the Student model have some required fields, and now we went to add Department While adding a department, We'll have to provide the All Student details(as shown in the attached image) else it'll give some error like field XYZ is required, In this case, how can I just add only the Department? Should I use Postman for it, or can we do it with Swagger as well? – Alcoholic May 25 '23 at 19:05
  • 1
    @Alcoholic Just change the Student property to `public ICollection? students { get; set; }` – Fitri Halim May 26 '23 at 01:11