Relationship one-to-Many Entity Framework

Asked

Viewed 132 times

2

I am developing a crud of registration for a project. When registering the user(Employee) must inform a IdCity that is related to the table cities(Cities). How is it possible for me to automatically manage to relate the column CityName at the Employee and show this on the screen?

City Class:

namespace cruddef.Models

    {
        public class City
        {
            [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
            public int CityId { get; set; }
            public string CityName { get; set; }

            public List<Employee> Employees { get; set; }
        }
    }

Employee class:

namespace cruddef.Models
{
    public class Employee
    {
        [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
        public int EmployeeId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string PhoneNumber { get; set; }
        public string Email { get; set; }

        public int? CityId { get; set; }
        public City City { get; set; }
    }
}

Context:

namespace cruddef.Models
{
    public class EmployeeContext : DbContext
    {
        public EmployeeContext(DbContextOptions options) : base(options)
        {
        }

        public DbSet<Employee> Employees { get; set; }
        public DbSet<City> Cities { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<City>().HasData(new City
            {
                CityId = 1,
                CityName = "Carlos Barbosa"
            }, new City
            {
                CityId = 2,
                CityName = "Bento Gonçalves"
            }, new City
            { 
                CityId = 3,
                CityName = "Garibaldi"
            }, new City
            {
                CityId = 4,
                CityName = "Farroupilha"
            }, new City
            {
                CityId = 5,
                CityName = "Oslo"
            });

            modelBuilder.Entity<Employee>().HasData(new Employee
            {
                EmployeeId = 1,
                FirstName = "Vinícius",
                LastName = "Bob",
                PhoneNumber = "999-888-7777",
                Email = "[email protected]",
                CityId = 1

            }, new Employee
            {
                EmployeeId = 2,
                FirstName = "Jan",
                LastName = "Kirsten",
                PhoneNumber = "111-222-3333",
                Email = "[email protected]",
                CityId = 2
            });
        }
    }
}

The result displayed on the screen is as follows:

0   
employeeId  1
firstName   "Vinícius"
lastName    "Bob"
phoneNumber "999-888-7777"
email   "[email protected]"
cityId  1
city    null
1   
employeeId  2
firstName   "Jan"
lastName    "Kirsten"
phoneNumber "111-222-3333"
email   "[email protected]"
cityId  2
city    null

1 answer

3


In your class Employee you have created the browsing properties and the property that receives the foreign key value, but at no time informs Entity that it should use this property as the foreign key to use in the relationship.

public class Employee
    {
        [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
        public int EmployeeId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string PhoneNumber { get; set; }
        public string Email { get; set; }

        public int? CityId { get; set; }
        [ForeignKey("CityId")]    //Indica ao entityframework que deve usar esta propriedade como chave estrangeira para usar no relacionamento.
        public City City { get; set; }
    }

It may be necessary to set up this relationship via fluency.

modelBuilder.Entity<Employee>().HasOptional(e => e.City).WithMany(c => c.Employees);
//Desta forma você configur o relacionameto das classes via FluenteAPI, onde um Employee não é obrigatário ter City, e um city pode ter mais de um Employee.

And in order for the loading of the related data to be included in the searches automatically, you need to create your navigational properties such as virtual, so you use the option lazy load for loading.

public class Employee
    {
        [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
        public int EmployeeId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string PhoneNumber { get; set; }
        public string Email { get; set; }

        public int? CityId { get; set; }
        [ForeignKey("CityId")]    //Indica ao entityframework que deve usar esta propriedade como chave estrangeira para usar no relacionamento.
        public virtual City City { get; set; }
    }

public class City
        {
            [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
            public int CityId { get; set; }
            public string CityName { get; set; }

            public virtual List<Employee> Employees { get; set; }
        }

At the time you make a search for some Job, you will already bring the information from Cityrelated to it, and the same will happen with the search in reverse mode, you searching for City will bring the list with all Employee related to this City researched.

using(var db = new SeuContext()){

    var city = db.Cities.First(c => c.id == algum_id); // Traz uma city ja com os employees relacionados

}

Try these changes and see if it works for you.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.