How to Map many one-to-many relationship in ASP.NET MVC? - c#

I have few Domain Models - Address, Customer, Employee, StoreLocation. Address has many to one relationship with Customerand Employee and one to one relationship with StoreLocation.
public class Address
{
public int Id;
public string Line1 { get; set; }
public string Line2 { get; set; }
public string Line3 { get; set; }
}
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
public IList<Address> Addresses { get; set; }
}
public class StoreLocation
{
public int Id { get; set; }
public string ShortCode { get; set; }
public string Description { get; set; }
public Address Address { get; set; }
}
public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime Dob { get; set; }
public IList<Address> Addresses { get; set; }
}
How to Map this relationship?. I am using ASP.NET MVC 3.0 and Entity Framework 4.1.

If you are using code-first (I think you want this, else, you have to edit your Q), the first way is the way explained below:
Entities:
public class Address {
[Key]
public int Id { get; set; }
public string Line1 { get; set; }
public string Line2 { get; set; }
public string Line3 { get; set; }
public virtual Customer Customer { get; set; }
public virtual StoreLocation StoreLocation { get; set; }
public virtual Employee Employee { get; set; }
public int? CustomerId { get; set; }
public int? EmployeeId { get; set; }
}
public class Customer {
[Key]
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Address> Addresses { get; set; }
}
public class StoreLocation {
[Key]
public int Id { get; set; }
public string ShortCode { get; set; }
public string Description { get; set; }
public virtual Address Address { get; set; }
}
public class Employee {
[Key]
public int Id { get; set; }
public string Name { get; set; }
public DateTime Dob { get; set; }
public virtual ICollection<Address> Addresses { get; set; }
}
DbContext inherited class:
public class ManyOneToManyContext : DbContext {
static ManyOneToManyContext() {
Database.SetInitializer<ManyOneToManyContext>(new ManyOneToManyInitializer());
}
public DbSet<Address> Addresses { get; set; }
public DbSet<Customer> Customers { get; set; }
public DbSet<StoreLocation> StoreLocations { get; set; }
public DbSet<Employee> Employees { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
modelBuilder.Conventions.Remove<IncludeMetadataConvention>();
modelBuilder.Entity<Customer>().HasMany(c => c.Addresses).WithOptional(a => a.Customer).HasForeignKey(a => a.CustomerId);
modelBuilder.Entity<StoreLocation>().HasRequired(s => s.Address).WithOptional(a => a.StoreLocation).Map(t => t.MapKey("AddressId"));
modelBuilder.Entity<Employee>().HasMany(e => e.Addresses).WithOptional(a => a.Employee).HasForeignKey(e => e.EmployeeId);
}
}
Context Initializer:
public class ManyOneToManyInitializer : DropCreateDatabaseAlways<ManyOneToManyContext> {
protected override void Seed(ManyOneToManyContext context) {
}
}
That will create the db-schema below:
Let me know if you have any questions or need clarifications on any part.

Related

cannot map entities using entity framework core

I have in database two tables: product, supplier
I want the entity framework to define the supplier of each product
I am getting data successfully for two tables but the supplier in the product table is null.
Also, the products collection in the supplier table is null.
this is my product class:
public class Product
{
public int id { get; set; }
[Column("Productname", TypeName = "ntext")]
public string Name { get; set; }
public decimal UnitPrice { get; set; }
public bool isDiscounted { get; set; }
public int quantity { get; set; }
public int SupplierId { get; set; }
[ForeignKey("SupplierId")]
public Supplier supplier { get; set; }
}
this is the class of supplier:
public class Supplier
{
public int Id { get; set; }
public string CompanyName { get; set; }
public string ContactName { get; set; }
public string ContactTitle { get; set; }
public string city { get; set; }
public string country { get; set; }
public string phone { get; set; }
public string Fax { get; set; }
public List<Product> Products { get; set; }
}
context class:
public class DbConext : DbContext
{
public DbSet<Product> Products { get; set; }
public DbSet<Supplier> Suppliers { get; set; }
public DbConext(DbContextOptions<DbConext> options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Product>().ToTable("Product");
modelBuilder.Entity<Supplier>().ToTable("Supplier");
modelBuilder.Entity<Product>().HasKey("id");
modelBuilder.Entity<Supplier>().HasKey("Id");
modelBuilder.Entity<Product>().HasOne(p => p.supplier).WithMany(s => s.Products).HasForeignKey(p => p.SupplierId);
}
}
This article might help.
You should use .Include() to load any related properties.
minimum you need is to initialize the list
public class Supplier
{
public int Id { get; set; }
public string CompanyName { get; set; }
public string ContactName { get; set; }
public string ContactTitle { get; set; }
public string city { get; set; }
public string country { get; set; }
public string phone { get; set; }
public string Fax { get; set; }
public List<Product> Products { get; set; }
public Supplier() {
this.Products = new List<Product>();
}
}

How to delete on cascade EF core

I'm trying to delete the entities related to each other when I remove a row, but it isn't deleting the related entities. It is only deleting one entity and not the others.
My model
public class Company
{
public int CompanyId { get; set;}
public string CompanyName { get; set; }
public int CompanySize { get; set; }
public string Branche { get; set;}
public string Description {get; set;}
public Recruiter Recruiter { get; set; }
public ICollection<Post> Posts { get; set; }
}
public class Recruiter
{
public int RecruiterId { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string PhoneNumber { get; set; }
public int CompanyId { get; set; }
public Company Company { get; set; }
}
public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Location { get; set; }
public int Compensation { get; set; }
public string Education { get; set; }
public string StartDate { get; set; }
public string Type { get; set; }
public string Profession { get; set; }
public string Language { get; set; }
public string Description { get; set; }
public string Hours { get; set; }
public bool Checked { get; set; }
public int CompanyId { get; set; }
public Company Company { get; set; }
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Post>()
.HasOne(post => post.Company)
.WithMany(company => company.Posts)
.IsRequired()
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.SeedDatabase();
}
The call I make. So when I delete a post, I want that all the related entities are being deleted.
public Post DeclinePostRequest(int postId)
{
var request = _dbContext.Posts.Where(post => post.PostId == postId).Include(post => post.Company).ThenInclude(company => company.Recruiter).FirstOrDefault();
if(!request.Checked)
{
_dbContext.Posts.Remove(request);
_dbContext.SaveChanges();
return request;
}
return null;
}
You are deleting the many side of a 1-to-many relationship there. Everything is working as expected.
Try deleting a Company instead.

navigation property is not loaded

I am using a objectDataSource to populate a gridview. I have 2 simple classes :
public class Employee
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Gender { get; set; }
public int Salary { get; set; }
public Department Department { get; set; }
}
and
public class Department
{
public int Id { get; set; }
public string Name { get; set; }
public string Location { get; set; }
public List<Employee> Employees { get; set; }
}
I also have
public class EmployeeDBContext : DbContext
{
public DbSet<Department> Departments { get; set; }
public DbSet<Employee> Employees { get; set; }
}
now in my EmployeeRepository class i have
public List<Department> GetDepartments()
{
EmployeeDBContext employeeDBContext = new EmployeeDBContext();
return employeeDBContext.Departments.Include("Employees").ToList();
}
Even though I have added .Include("Employees"), the employees are missing in gridview. what am I doing wrong here?
First of all, you will need to have a foreign key (DepartmentId) inside Employee class. I do not know how the video got away with that.
public class Employee
{
public int Id { get; set; }
public int DepartmentId { get; set; } <=====
public string FirstName { get; set; }
public string LastName { get; set; }
public string Gender { get; set; }
public int Salary { get; set; }
public virtual Department Department { get; set; }
^^^^^^^
}
public class Department
{
public int Id { get; set; }
public string Name { get; set; }
public string Location { get; set; }
public virtual ICollection<Employee> Employees { get; set; }
^^^^^^^^^^^^^^^^^^
}
public partial class EmployeeDBContext : DbContext
{
public virtual DbSet<Employee> Employee { get; set; }
public virtual DbSet<Department> Department { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// Optional, but good practice to have the mapping here.
modelBuilder.Entity<Department>()
.HasMany(e => e.Employee)
.WithRequired(e => e.Department)
.HasForeignKey(e => e.DepartmentId);
}
}
- OR -
Add DepartmentId property and [ForeignKey] data annotation to Department.
public class Employee
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Gender { get; set; }
public int Salary { get; set; }
public int DepartmentId { get; set; } <===
// Optional, but good practice to have this data annotation attribute.
[ForeignKey("DepartmentId")] <===
public Department Department { get; set; }
}
FYI: You want to use virtual, in case someone wants to use lazy loading in the future.
have you tried something like this
return employeeDBContext.Departments.Include(x =>x.Employees ).ToList(); ?

Entity Framework 6 asp.net Code First Setup

Hi guys I am spinning wheels on this one. I am using EF6 and ASP.Net 4.6. I have a given table which has student information and parent information. A student can have many parents and a parent can have many students. Call this table 'Contact'. I am to create a table called 'Request' which will hold information for a parent submitting a request for his student. I will create a lookup table with two columns, one for student id and one for parent id called 'StudentParents'. I want to be able to have the parent log in, select his student from a drop down of all of his students and submit the request. The many to many relationship is throwing me off as far as my include statements. How can I get EF to set up this structure so that when I GetRequest(id) I can get the Student info and the Parent info to be included? Here is my code that wont Include anything other than the request.
public class Contact
{
[Key]
public int id { get; set; }
public string student_id { get; set; }//This is the Student ID
public string last_name { get; set; }
public string first_name { get; set; }
public string middle_initial { get; set; }
public string grade { get; set; }
public int current_school_id { get; set; }
public string current_school_name { get; set; }
[Display(Name = "Parent Last Name")]
public string contact_first_name { get; set; }
[Display(Name = "Parent Middle Name")]
public string contact_middle_name { get; set; }
[Display(Name = "Parent Last Name")]
public string contact_last_name { get; set; }
public string contact_relationship { get; set; }
[Display(Name = "Parent Email")]
public string contact_email { get; set; }
[Display(Name = "Parent Address")]
public string login { get; set; }//This is the Parent ID
public string Classif_description { get; set; }
}
public class Request
{
[Key]
public int id { get; set; }
public Student student_id { get; set; }
public Contact login { get; set; }
[Display(Name = "First School Choice")]
public string firstSchool { get; set; }
[Display(Name = "Second School Choice")]
public string secSchool { get; set; }
[Display(Name = "Rising Grade")]
public string rising_grade { get; set; }
public DateTime ReqSubmitted { get; set; }
public string ReqStatus { get; set; }
public DateTime Created { get; set; }
public DateTime Modified { get; set; }
public string ModifBy { get; set; }
}
public class Parent
{
public int id { get; set; }
public string contact_first_name { get; set; }
public string contact_middle_name { get; set; }
public string contact_last_name { get; set; }
public string contact_relationship { get; set; }
public string contact_email { get; set; }
public string contact_address { get; set; }
public string contact_city { get; set; }
public string contact_zip { get; set; }
[Key]
public string login { get; set; }
public string contact_pw { get; set; }
public string phone { get; set; }
public string phone_type { get; set; }
public Parent() { }
public virtual ICollection<Student> Students { get; set; }
}
public class Student
{
[Key]
public int id { get; set; }
public int student_id { get; set; }
public string last_name { get; set; }
public string first_name { get; set; }
public string middle_initial { get; set; }
public DateTime birthdate { get; set; }
public string gender { get; set; }
public string grade { get; set; }
public string Fed_race_description { get; set; }
public string Classif_description { get; set; }
public int current_school_id { get; set; }
public string current_school_name { get; set; }
public int home_school_id { get; set; }
public string home_school_name { get; set; }
public Student()
{
this.Parents = new HashSet<Parent>();
}
public virtual ICollection<Parent> Parents { get; set; }
}
public class OEContext : DbContext
{
public OEContext() : base("name=OEContext")
{
}
public DbSet<Request> Requests { get; set; }
public DbSet<Parent> Parents { get; set; }
public DbSet<Contact> Contacts { get; set; }
public DbSet<Student> Students { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Parent>()
.HasMany(s => s.Students)
.WithMany()
.Map(x =>
{
x.MapLeftKey("login");
x.MapRightKey("student_id");
x.ToTable("StudentParents");
}
);
base.OnModelCreating(modelBuilder);
}
}
Changed the strategy. Made Request have many Contacts. So I added a constructor to the request:
public Request()
{
Contacts = new List<Contact>();
}
public virtual ICollection<Contact> Contacts { get; set; }
Next I changed the contact class:
public int ContactId { get; set; }
public Contact() { }
public virtual Request Request { get; set; }
With this relationship I can pull both Parents and a student from the Contacts associated with the Request.

Add Foreign Key in Table in ASP.NET MVC in code first

I want to have a one to many relationship in between instructor and course. How can I achieve it? Below is what I have as of now.
public class Instructor
{
//[Key]
public int id { get; set; }
public string name { get; set; }
public string address { get; set; }
public string email { get; set; }
}
public class Course
{
//[Key]
public int id { get; set; }
[DisplayName("Course")]
[Required(ErrorMessage = "CSExxx")]
public string progId { get; set; }
public string name { get; set; }
public string semester { get; set; }
public string description { get; set; }
public virtual Instructor instructor { get; set; }
}
You need to add a virtual collection of Course to Instructor
public class Instructor
{
//[Key]
public int id { get; set; }
public string name { get; set; }
public string address { get; set; }
public string email { get; set; }
public virtual ICollection<Course> Courses { get; set; }
}
public class Course
{
//[Key]
public int id { get; set; }
[DisplayName("Course")]
[Required(ErrorMessage = "CSExxx")]
public string progId { get; set; }
public string name { get; set; }
public string semester { get; set; }
public string description { get; set; }
public virtual Instructor instructor { get; set; }
}
In OnModelCreating in your DataContext
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Instructor>().HasMany(i => i.Courses).WithRequired(c => c.Instructor).HasForeignKey(c => c.instructor).WillCascadeOnDelete(true);
}

Categories

Resources