Problem loading data with Entity Framework using Include

1

I'm using the Entity Framework with MySql on my system and I need to do a specific query that includes a list of a Model ( ApplicationUser ), in this list each returned object has in its properties another Model . That is, each 'ApplicationUser' has a list of type 'Vehicle' (one-to-many) and each vehicle has its < strong> ApplicationUser , but when I'm going to use direct view , I notice that the driver of each vehicle is always null, even though I give include this way:

>
context.Veiculos.Include(veiculo => veiculo.Motorista).ToList();

Vehicle Model:

 [DisplayColumn("Nome")]
    [Table("Veiculos")]
    public class Veiculo
    {
        [Key]
        public Guid VeiculoID { get; set; }

        [Required]
        public Guid MotoristaID { get; set; }
        //[Required]
        //public Guid EnderecoID { get; set; }

        [Required]
        public Guid EmpresaID { get; set; }

        //[Display(Name = "Address", ResourceType = typeof(Resources.Language))]
        //public virtual Endereco Endereco { get; set; }

        [Display(Name = "Company", ResourceType = typeof(Resources.Language))]
        public virtual ApplicationUser Empresa { get; set; }

        [Display(Name = "Driver", ResourceType = typeof(Resources.Language))]
        public virtual ApplicationUser Motorista { get; set; }

        [Required]
        [Display(Name = "Mark", ResourceType = typeof(Resources.Language))]
        public string Marca { get; set; }

        [Required]
        [Display(Name = "Model", ResourceType = typeof(Resources.Language))]
        public string Modelo { get; set; }

        [Required]
        [Display(Name = "Year", ResourceType = typeof(Resources.Language))]
        public int Ano { get; set; }

        [Required]
        [Display(Name = "LicensePlate", ResourceType = typeof(Resources.Language))]
        public string Placa { get; set; }

        [Required]
        [Display(Name = "Color", ResourceType = typeof(Resources.Language))]
        public string Cor { get; set; }

        [Required]
        [Display(Name = "RENAVANCode", ResourceType = typeof(Resources.Language))]
        public long Renavan { get; set; }

        [Required]
        [Display(Name = "NumberOfPassangers", ResourceType = typeof(Resources.Language))]
        public int NumeroPassageiros { get; set; }

        [Display(Name = "ExtraBaggage", ResourceType = typeof(Resources.Language))]
        public double PesoExtra { get; set; }

        [Required]
        [Display(Name = "Trailer", ResourceType = typeof(Resources.Language))]
        public bool Carretinha { get; set; }

        [Display(Name = "Excluded", ResourceType = typeof(Resources.Language))]
        public bool Excluido { get; set; }
    }

ApplicationUser model:

public class ApplicationUser : IdentityUser
    {
        public ApplicationUser()
        {
            Clients = new Collection<Client>();
        }

        [Index, MaxLength(60)]
        public override string UserName { get; set; }

        public Guid? EmpresaPaiID { get; set; }
        public Guid? EnderecoID { get; set; }
        public Guid? ServicoID { get; set; }
        public bool Ativo { get; set; }
        public bool CadastroCompleto { get; set; }

        [Display(Name = "Address", ResourceType = typeof(Resources.Language))]
        public virtual Endereco Endereco { get; set; }
        [Display(Name = "Vehicles", ResourceType = typeof(Resources.Language))]
        public virtual ICollection<Veiculo> Veiculos { get; set; }
        [Display(Name = "ServicesPerformed", ResourceType = typeof(Resources.Language))]
        public virtual ICollection<Servico> ServicosVans { get; set; }

        [Display(Name = "Available", ResourceType = typeof(Resources.Language))]
        public bool Disponivel { get; set; }        

        [Required]
        [Display(Name = "Name", ResourceType = typeof(Resources.Language))]
        public string Nome { get; set; }

        [Display(Name = "CompanyName", ResourceType = typeof(Resources.Language))]
        public string NomeDaEmpresa { get; set; }

        [Required]
        [Display(Name = "UserType", ResourceType = typeof(Resources.Language))]
        public TipoUsuario TipoUsuario { get; set; }

        [Required]
        [Display(Name = "CelPhone", ResourceType = typeof(Resources.Language))]
        public override string PhoneNumber { get; set; }

        [Display(Name = "Phone", ResourceType = typeof(Resources.Language))]
        public string Telefone { get; set; }

        [Required]
        [Display(Name = "RG", ResourceType = typeof(Resources.Language))]
        public string RG { get; set; }

        [Cpf]
        [Required]
        [Display(Name = "CPF", ResourceType = typeof(Resources.Language))]
        public string CPF { get; set; }

        [Cnpj]
        [Display(Name = "CNPJ", ResourceType = typeof(Resources.Language))]
        public string CNPJEmpresa { get; set; } //Caso for empresa o tipo de usuário

        //[Cnpj]
        //[Display(Name = "RentalCNPJ", ResourceType = typeof(Resources.Language))]
        //public string CNPJLocadora { get; set; }

        [Required]
        [Display(Name = "Gender", ResourceType = typeof(Resources.Language))]
        public string Sexo { get; set; }        

        public double Latitude { get; set; }

        public double Longitude { get; set; }

        [Display(Name = "PassangerSecurity", ResourceType = typeof(Resources.Language))]
        public bool SeguroPassageiro { get; set; }

        [Display(Name = "RemuneratedActivity", ResourceType = typeof(Resources.Language))]
        public bool AtividadeRemunerada { get; set; }

        [Display(Name = "DriverLicense", ResourceType = typeof(Resources.Language))]
        public long CNH { get; set; }

        [NotMapped]
        [Display(Name = "Photo", ResourceType = typeof(Resources.Language))]
        public HttpPostedFileBase Foto { get; set; }

        [NotMapped]
        [Display(Name = "DocumentOfTheCarRentalAgency", ResourceType = typeof(Resources.Language))]
        public HttpPostedFileBase DocumentoLocadoraVeiculos { get; set; }

        [NotMapped]
        [Display(Name = "CertificateOfCriminalRecord", ResourceType = typeof(Resources.Language))]
        public HttpPostedFileBase AtestadoAntecedentesCriminais { get; set; }

        [NotMapped]
        [Display(Name = "TicketDPVAT", ResourceType = typeof(Resources.Language))]
        public HttpPostedFileBase BilheteDPVAT { get; set; }

        [NotMapped]
        [Display(Name = "VehicleLicensingRegistration", ResourceType = typeof(Resources.Language))]
        public HttpPostedFileBase RegistroLicenciamentoVeiculo { get; set; }

        public string FotoPath { get; set; }
        public string DocumentoLocadoraVeiculosPath { get; set; }
        public string AtestadoAntecedentesCriminaisPath { get; set; }
        public string BilheteDPVATPath { get; set; }
        public string RegistroLicenciamentoVeiculoPath { get; set; }

        public virtual ICollection<Client> Clients { get; set; }

In view , I notice that Motorista is not loaded by this query. This generates a zero reference error, obviously. Would it have something to do with Lazy Loading ?

How to solve?

If you need to paste the database diagram here.

    
asked by anonymous 06.06.2015 / 01:40

1 answer

1

As you can see, the Vehicle class has two FKs for ApplicationUser. They are Company and Driver.

public class Veiculo
{
    [Key]
    public Guid VeiculoID { get; set; }

    [Required]
    public Guid MotoristaID { get; set; }

    [Required]
    public Guid EmpresaID { get; set; }

    public virtual ApplicationUser Empresa { get; set; }

    public virtual ApplicationUser Motorista { get; set; }
}

EF can not have a single collection for two FKs. As in the class below:

public class ApplicationUser : IdentityUser
{
    public virtual ICollection<Veiculo> Veiculos { get; set; }
}

It is necessary to have two collections (CompanyVehicles and VehicleMotorist), so that each one represents the reverse part of the relation Vehicle - > ApplicationUser. If you need a collection that brings all vehicles, it can be done through another property (Vehicles).

public class ApplicationUser : IdentityUser
{
    public virtual ICollection<Veiculo> VeiculosEmpresa { get; set; }
    public virtual ICollection<Veiculo> VeiculosMotorista { get; set; }

    public virtual IEnumerable<Veiculo> Veiculos
    {
        get { return VeiculosEmpresa.Concat(VeiculosMotorista); }
    }
}

For this to work, you need to include a fluent mapping in the OnModelCreating method. In this way, we are informing Model Builder which property is reflected by which collection, and its respective FK.

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
     modelBuilder.Entity<Veiculo>().HasRequired(m => m.Empresa).WithMany(m => m.VeiculosEmpresa).HasForeignKey(p => p.EmpresaID);
     modelBuilder.Entity<Veiculo>().HasRequired(m => m.Motorista).WithMany(m => m.VeiculosMotorista).HasForeignKey(p => p.MotoristaID);
}
    
06.06.2015 / 02:39