I have two tables that I need to join
employee
-id
-name
-department_id
and
department
-id
-department_name
How can I handle the joined data in a single class? Should I create properties for all the data for each table?
e.g
class employeerecord
{
private int id {get; set;}
private string name {get; set;}
private int department_id {get; set;}
private string department_name {get; set;}
}
Right now, I'm using a datatable for viewing joined tables.
The whole design should include all entities you have in your database, i.e. there's departament table, there should be corresponding class. Same applies to employee table. You should have following classes:
class Employee
{
public int id {get; set;}
public string name {get; set;}
public int department_id {get; set;}
public Departament department {get; set;}
}
class Departament
{
public int id {get; set;}
public string name {get; set;}
//public ICollection<Employee> Employees { get; set; }
}
When loading data, you should wirte join query, to populate both: Employee instance and Departament instance.
You can uncomment commented line, if you'd like to have list of employees in particular departament.
This solely depends on what you want to do with this classes. You can go either way.
If you want to display a single employee and that employee can only belong to one department, then nothing speaks against a flat model:
class employeerecord
{
private int id{get;set};
private string name{get;set;}
private int department_id{get;set;}
private string department_name{get;set;}
}
If an employee can be a member of multiple Departments, you are better off storing the departments in a collection:
public class EmployeeViewModel
{
public int id{get;set};
public string name{get;set;}
public IEnumerable<Deparment> Departments { get; set; }
}
The same goes for departments. A department will most likely consist of multiple employees:
public class DepartmentViewModel
{
public int id{get;set};
public string name {get;set;}
public IEnumerable<Employee> Employees { get; set; }
}
And there is no reason, why you can't do all at once and use the classes depending on your specific use case.
Related
I have two class that you can see below:
public class Product
{
public int Id {get; set;}
public string Name {get; set;}
public decimal SuggestionPrice {get; set;}
public List<SaleOrder> SaleOrders {get; set;} = new List<SaleOrder>();
}
public class SaleOrder
{
public int Id {get; set;}
public List<Product> Products {get; set;} = new List<Product>();
}
as you can see,this two class have Many-To-Many RealationShip to eachother.in Product class i have SuggestionPrice property that i want save multiple value in it and it's difference for each SaleOrder Class.
for example,Someone offers $ 1,000 in one SaleOrder and someone else offers $ 2,000 in another SaleOrder for same product and infinitely another suggestions that I want to save them all in database.
problem is i don't know how can i do this?how can i know witch SuggestionPrice is for witch SaleOrder Class?
To save in database You should create a SuggestionPrice table like this:
public class SuggestionPrice
{
public int Id {get;set}
public int ProductId {get;set;}
public decimal Price {get;set;}
public Product Product {get;set;}
}
and change product class to this:
public class Product
{
public int Id {get; set;}
public string Name {get; set;}
public ICollection<SuggestionPrice> SuggestionPrices {get; set;}
}
to create a one to many relation between Product and SuggestionPrice.
I want to get some records from Database that depends on three tables.
Three tables are:
1.Company(Id,Name)
2. Car(Id,CompanyId,Name)
3. Showroom(Id,CarId,Name)
Now a one company contains many cars and many cars may exist in many showrooms.
I want to get records from showroom table where company '2' cars exist along with cars. Is it possible to do it in entity framework core?
I think your entities will be like :
Company
public class Company
{
public int Id {get; set;}
public string Name {get; set;}
public ICollection<Car> Cars {get; set;}
}
Car:
public class Car
{
public int Id{get; set;}
public string Name {get; set;}
public int CompanyId{get; set;}
public Company Company {get; set;}
}
ShowRoom:
public class ShowRoom
{
public int Id{get; set;}
public string Name {get; set;}
public int CarId{get; set;}
public Car Car{get; set;}
}
In your method:
var context = new SomeContext();
var showRooms= context.ShowRooms
.Include(x=> x.Car)
.ThenInclude(x=> x.Company)
.Where(x=> x.Car.Company.Id== 2)
.ToList();
I have a table that contains 2 foreign key that reference separately to 2 different table.
I would like to return the result of all person that has course of "Science".
How to retrieve the record back using LINQ?
This is what i gotten so far:
return
_ctx.Person
.Include(u => u.Course
.Where(ug=>ug.CourseName== "Science"));
This is not working as it shows the error.
The Include path expression must refer to a navigation property
defined on the type
public class Course
{
public int CourseID {get; set;}
public string CourseName {get; set;}
public virtual ICollection<Person> Persons { get; set; }
}
public class Person
{
public int PersonID {get; set;}
public virtual ICollection<Course> Courses { get; set; }
}
This is the mapping table. Only contains 2 foreign key from 2 different table.
I could not use this table inside the solution.As the code first won't generate this table as it doesn't contain it's own PK.
//This is not shown in the EntityFramework when generating Code First.
public class PersonCouseMap
{
public int PersonID {get; set;}
public int CourseID {get; set;}
}
Update : this works after I switched the entity.
return _ctx.Course
.Include(u=>u.Person)
.Where(ug=>ug.CourseName == "Sciene");
Anyone can explain why it won't work the another way round.
I need to display a List of Person who have course of "Science",
not Course Science that has a list of user.
The original query does not work because you've pushed the Where predicate inside the Include expression, which is not supported as indicated by the exception message.
The Include method is EF specific extension method used to eager load related data. It has nothing to do with the query filtering.
To apply the desired filter person that has course of "Science" you need Any based predicate since the Person.Courses is a collection:
return _ctx.Person
.Where(p => p.Courses.Any(c => c.CourseName == "Science"));
To include the related data in the result, combine it with Include call(s):
return _ctx.Person
.Include(p => p.Courses)
.Where(p => p.Courses.Any(c => c.CourseName == "Science"));
It looks like there is no relations between these two entites, you can establish a relationship by making the following changes to your code:
Here I am assuming that you want to establish Many-to-Many relationship between these two tables by having a third entity PersonCourseMap
public class Course
{
public int CourseID {get; set;}
public string CourseName {get; set;}
public virtual ICollection<CoursePersons> Courses { get; set; }
}
public class Person
{
public int PersonID {get; set;}
public virtual ICollection<PersonCourse> Courses { get; set; }
}
public class PersonCourseMap
{
public int PersonID {get; set;}
public int CourseID {get; set;}
public virtual ICollection<Person> Persons { get; set; }
public virtual ICollection<Course> Courses { get; set; }
}
After making above changes you can simply navigate through properties.
Include Foreign Key Mapping
public class Course
{
public int CourseID {get; set;}
public string CourseName {get; set;}
public virtual ICollection<Person> Person {get; set}
}
public class Person
{
public int PersonID {get; set;}
public virtual ICollection<Course> Course {get; set;}
}
using System.ComponentModel.DataAnnotation.Schema;
public class PersonCouseMap
{
[ForeignKey("Person")]
public int PersonID {get; set;}
[ForeignKey("Course")]
public int CourseID {get; set;}
public virtual ICollection<Person> Person {get; set;}
public virtual ICollection<Course> Course {get; set;}
}
I am trying to get the correct mapping between 4 tables.
MainTables
Class(Id, ClassName)
Course(Id, CourseName)
Student(Id, StudentName)
Relationship tables
ClassCourse(Id, ClassId, CourseId)
ClassCourseStudent(ClassCourseId, StudentId)
Class to Course has Many to Many mapping. So we use a relationship table ClassCourse to store the relationship
Student has one to Many mapping with ClassCourse.
So my question is how can I do the mapping for Student and ClassCourse
My code is
public class Class
(
public int Id {get;set;}
public string ClassName {get;set;}
public virtual ICollection<Course> Courses {get;set;}
)
public class Course
(
public int Id {get;set;}
public string CourseName {get;set;}
public virtual ICollection<Student> Students {get;set;}
)
public class Student
(
public int Id {get;set;}
public string StudentName {get;set;}
)
modelBuilder.Entity<Class>().ToTable("Class");
modelBuilder.Entity<Course>().ToTable("Course");
modelBuilder.Entity<Student>().ToTable("Student");
modelBuilder.Entity<Class>().HasMany(c => c.Courses).WithMany().Map(m => m.ToTable("ClassCourse")
m.MapLeftKey("ClassId")
m.MapRightKey("CourseId")
)
modelBuilder.Entity<Course>().HasMany(c => c.Students).WithMany().Map(m =>
m.ToTable("ClassCourseStudent")
m.MapLeftKey("ClassCourseId")
m.MapRightKey("StudentId")
The last mapping is the one I am looking for.
Thanks in advance.
I think you have to revisit your design. Right now you're trying to assign a composite key as foreign key, which can't be done.
What I would do is create a separate model that simply stores the course-class combination and provides a single key to reference. This will result in an extra table, but allows you to do what you want.
class Student {
public int StudentId {get; set;}
}
class Class {
public int ClassId {get; set;}
}
class Course {
public int CourseId {get; set;}
}
class ClassCourse {
public int ClassCourseId {get; set;}
public int ClassId {get; set;}
public int CourseId {get; set;}
}
Now every class should have a list of ClassCourse objects instead of Course, and every Course should have a list of ClassCourse objects. Now they're not directly linked together but are still connected trough an intermediate object and you can connect your Student objects to the primary key of ClassCourse.
I am trying to learn Entity framework. Say, I have the following classes
class Course
{
[Key]
public virtual int CourseID {get; set;}
public virtual string CourseName {get; set;}
}
class CourseDBContext:DBContext
{
public DbSet<Course> Courses{get;set;}
}
Then I can use Linq to query the database as shown below
using (CourseDBContext a = new CourseDBContext())
{
var b = from c in a.Course
where c.CourseID == 1001
select c;
var d = b.FirstOrDefault();
if(d != null)
Console.WriteLine(d.CourseName);
}
This works fine. Now if I add a second class
class Assignment
{
[Key]
public virtual int CourseID {get; set;}
public virtual int StaffID {get; set;}
}
class AssignmentDBContext:DBContext
{
public DbSet<Assignment> Assignments{get;set;}
}
Now, How can I use Linq to select and display the CourseName and StaffID associated with CourseID = 1001?
The example above is contrived and so the table design and fields are irrelevant. I just want to know how to query the data between two classes from two different database tables using Entity Framework and Linq.
Thanks
Both entities need to be in the same context.
public class CoursesContext: DbContext
{
public DbSet<Assignment> Assignments {get; set;}
public DbSet<Course> Courses {get; set;}
}
You can add an Assignment navigation property to filter on a foreign key:
public class Course
{
[Key]
public virtual int CourseID {get; set;}
public virtual string CourseName {get; set;}
public virtual Assignment {get; set;}
}
Then you can query like so:
var staffId =
from c in a.Course
where c.CourseID == 1001
select c.Assignment.StaffID;
Don't have a seperate context for each DbSet. I.e
class MyDbContext : DBContext
{
public DbSet<Course> Courses{get;set;}
public DbSet<Assignment> Assignments{get;set;}
}