Create classes when reading from multiple tables in C# - c#

I have tables in the database named
Students (StudentId,Name,Address)
Subjects (SubjectId,SubName)
Stud_Subjects (StudentId,SubjectId)
And I hv created c# classes for Student and Subject. I want to take data from Stud_Subjects table do i need to create another class named "Stud_Subject". How to add add properties to that class.
lets say I want to get data joining these tables and the result should be like this.
(StudentId,Name,SubName)
How to map these result into C# class. do i have to create another class with above three fields.

Two classes is enough. One for Student one for Subject. It looks like Stud_Subjects table is for "Many-Many relationship", you can implement that via a collection.
class Student
{
public int StudentId { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public List<Subject> Subjects { get; private set; }
}
class Subject
{
public int SubjectId { get; set; }
public string SubjectName { get; set; }
public List<Student> Students { get; private set; }
}
Subjects collection in Student class will have all the subjects which a student is mapped and Students collection in Subject class will have all the students which is mapped to current Subject.
You could also consider converting List<T> to Dictionary<int, Student> and Dictionary<int, Subject> for easy access them via their Ids

Related

How do I get the id of record in foreign key table using another column in that table in ASP.NET MVC?

I am new to ASP.NET MVC. Using Entity Framework 6, I am working on a project to store employee skills in a database. The user can enter a new skill into a list of skills. I would like to keep track of who added the new skill. I have a table of all of the employees.
These are the models for the two tables.
public partial class Skill
{
public int ID { get; set; }
public string Skill { get; set; }
[ScaffoldColumn(false)]
public int LastActionUserID { get; set; }
public virtual Employee Employees { get; set; }
}
public partial class Employee
{
public int ID { get; set; }
public string EmployeeLAN { get; set; }
public int LastActionUserID { get; set; }
public virtual Employee Employees { get; set; }//References itself for LastActionUserID
public virtual ICollection<Skill> Skills{ get; set; } //Omitted in initial question
}
There is a 1 to Many mapping of Employee to Skill. I can get the current user's EmployeeLAN but how do I get the id of that Employee record to put into the Skill table automatically when then new skill is created? Must I convert the table to an enumerable object and use SingleOrDefault or LINQ? Or is there an easier way using EF6? Also, setting this automatically when a new skill is created would be done in the controller, correct?
You're on the right track and you should continue to use EF6.
The Employee class should have a Skills list. That way you can call myEmployee.Skills and have a list of all the skills available.
public partial class Employee
{
public int ID { get; set; }
public string EmployeeLAN { get; set; }
public int LastActionUserID { get; set; }
public virtual ICollection<Skill> Skills{ get; set; }
}
Also, setting this automatically when a new skill is created would be done in the controller, correct?
You'll need to add to the Skills list, call AddOrUpdate() to mark this as changed, then SaveChanges() to persist it to the database.
I recommend learning more from the MSDN docs and Julie Learman's
Entity Framework videos on Pluralsight

Issue with navigation properties in EntityFramework 6

If I have a Course class, that has a collection of students (ICollection<Person>) as follows:
public class Person
{
public Person()
{
this.Courses = new HashSet<Course>();
}
public int PersonId { get; set; }
[Required]
public string PersonName { get; set; }
public virtual ICollection<Course> Courses { get; set; }
}
public class Course
{
public Course()
{
this.Students = new HashSet<Person>();
}
public int CourseId { get; set; }
public string CourseName { get; set; }
public virtual ICollection<Person> Students { get; set; }
}
I end up with this structure in the database (as expected):
(note the PersonCourses table)
However, in my example, I also want to add an instructor to the course.
This instructor is also a Person, who can attend courses just like everyone else, so I adjust the above classes as shown below:
public class Person
{
public Person()
{
this.Courses = new HashSet<Course>();
}
public int PersonId { get; set; }
[Required]
public string PersonName { get; set; }
public virtual ICollection<Course> Courses { get; set; }
public virtual ICollection<Course> InstructedCourses { get; set; }
}
public class Course
{
public Course()
{
this.Students = new HashSet<Person>();
}
public int CourseId { get; set; }
public string CourseName { get; set; }
public virtual ICollection<Person> Students { get; set; }
public virtual Person Instructor { get; set; }
}
What I was expecting to see is the same database structure as above, but with an additional table created that linked a person to many courses.
However, what I got was this:
(Note that the PersonCourses table has gone)
What I was Expecting/Hoping to see was similar to this:
It's probably worth stating that the reason I've not got a separate Instructor/Person class is that I'm expecting that any Person can create a course, and thus become an instructor for that course.
Firstly - Is this possible to achieve via code-first in EF? I'm assuming so..
Secondly - What is it I'm doing wrong?
Thirdly - Is it the weekend yet?
All help appreciated :)
This is one reason I don't like / recommend code-first. It looks like EF got confused with the second InstructedCourses collection and instead just set up the instructor reference back from the course, though it seems to have just made the students collection a 1-to-many as well.
I would seriously consider either:
A) changing you domain to define an Instructor entity vs. Student entity
or
B) Do schema first with the proper EF mappings to the tables you want.
I don't think any DBA is going to want to see things like course_personId / Person_personId throughout the schema that they are one day going to need to support and optimize.
Instructors and Students can extend a base "Person" class with either table per entity or an identifier. Course to instructor and course to student relationships can then be defined more clearly. The limitation would be if you wanted the same "person" to be able to be referenced as both an instructor and a student.

How many to many relationship table do I draw data with code-first?

I have two tables in my student's name and course name. There is a lot of relationship between them. How do I draw the lessons of the learner? Below are the entities I wrote.
public class Student
{
public Student()
{
Lessons = new HashSet<Lesson>();
}
public int ID { get; set; }
public int MaxCredit { get; set; }
public int MemberID { get; set; }
public virtual Member Member { get;
public virtual ICollection<Lesson> Lessons { get; set; }
}
public class Lesson
{
public Lesson()
{
Students = new HashSet<Student>();
}
public int ID { get; set; }
public string Name { get; set; }
public int LessonCredit { get; set; }
public virtual ICollection<Student> Students { get; set; }
}
I tried to get a students lessons with:
uow.LessonRepository.GetALL().Where(x=> x.Students.Any(s=> s.MemberID==id))
but it gave me a casting error.
Your EF model is correct, to do a many to many relationship both sides have a virtual ICollection<T> of the other type.
Your query isn't right though if you want to get a student's lessons, parsing it we start with a LessonRepository (presumably an IEnumerable<Lesson>) and then do a Where on it to filter the collection down; so far so good (a bit odd starting with the lessons, but whatever). The condition is (in English) where there are any students with a MemberId matching "id" (wherever that came from). Not exactly sure what that would give you, but its not a student's lessons.
Since you already have the navigation property, you can just access the Lessons property of a given student object. Assuming you started with a student id something like:
Students.FirstOrDefault(s => s.Id == id)?.Lessons;
FirstOrDefault searches for the correct student item and then you just access the Lessons property.

Am I building the wrong entities in MVC?

Goal. I have a "Gift" entity that describes what someone has to offer (babysitting, dog walking, etc) with a rating. And I want a "GiftCategory" entity that gives general category descriptive information (pets, sports, automotive, etc) for someone to search apon and then get all gift that have those categories. A "Gift" entity can have multiple "GiftCategory" entities associated with it. I want the ability to search for a category and pull out all "Gift" entities that have been created with those categories associated with them. Here is what I have so far but it doesn't seem to work with the entity first approach. Maybe I need another table that connects the two entities because currently the way the two tables are connected doesn't seem correct?
Gift entity:
public class Gift
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<GiftCategory> Categories { get; set; } // is this incorrect???
public int Rating { get; set; }
}
Category entity:
public class GiftCategory
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
The "GiftCategory" table that gets created creates a gift_id column that links the "GiftCategory" back to a gift (not what I want)!!!!
It seems like I would need to create a entity that connects the two entities? Something like:
public class ConnectGifts
{
public int Id { get; set; }
public string GiftId{ get; set; }
public string GiftCategoryID{ get; set; }
}
This way I can have multiple categories for a Gift, but the thing I don't understand is with entity first I really don't need this entity I just need what would be this table to get/query the "GiftCategory" entities for ids then get the gift ids to get all the gifts. So it seems like creating this entity is overkill? Is there a way to do it without creating a third table/entity ("ConnectGifts") with code first? Or am I not understanding that all entities are tables and all tables are entities? I'm also using linq-to-sql for all querying.
You're looking for a many-to-many relationship and can be defined as:
public class Gift
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<GiftCategory> Categories { get; set; } // is this incorrect???
public int Rating { get; set; }
}
public class GiftCategory
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<Gift> Gifts { get; set; }
}
So each has a collection of the other. Gift has many Categories and Category had many Gifts. You could use a bridge table like you've done with ConnectGifts but it's not necessary with EF. Using just Gift and GiftCategory, EF will actually create the bridge table for you.

MVC 3 many to many relationship and ViewModels

I have a situation where I have a many to many relationship in my model between Student and Lesson. In most cases Lessons are 1 on 1 where a single student attends the lesson but there are situations where a lesson is shared by more than one student (hence the many to many).
So my ViewModel looks a little like this:
public class ScheduleViewModel
{
public Lesson Lesson { get; set; }
public List<StudentViewModel> Students { get; set; }
public List<StudentViewModel> AllStudents { get; set; }
}
In the View I would bind the Lesson properties using DisplayFor to show the details of the Lesson. Then I would have a DropDownListFor which uses AllStudents as its source. When a user selects a Student from the list a second DropDown would be generated (etc) allowing further Students to be added. These selections will be added to the Students property of my ViewModel.
In the past I would have handled this is javascript and managed the updating via JSON and AJAX. My instinct is that I should be using MVC Templates for this but in my research I've not found an example that has this exact scenario (or of course I may be barking up the wrong tree).
I have no code for my View at the moment as I'm really stuck on the right strategy to use in this case.
I hope that makes sense and any help on this greatly appreciated.
Many Thanks
Simon.
Your Lesson class should have a binding for Students, something like this:
Lesson.cs
public class Lesson
{
public int Id { get; set; }
public string Name { get; set; }
public virtual List<Student> Students { get; set; }
}
Then in your Student class you would bind a relation to lessons:
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public virtual List<Lesson> Lessons { get; set; }
}
Now you have a many-to-many relationship between Lesson and Student.
Your viewmodel would then look more like this:
public class ScheduleViewModel
{
public Lesson Lesson { get; set; }
// All students property
public List<Student> Students { get; set; }
}
Your Lesson property now contains all the information about your lesson, including which Students are connected to it, because it has a List of Students. You want to add the selected students from your view to this list.
The Students property is used to display all students in the database.

Categories

Resources