Problem with inheritance

3

I have a problem with a search in the bank, I will try to explain it in the best possible and clearest way.

I have a Pessoa table and a Cliente table, the last one inherits from Pessoa , I also have a Unidade table and a MensagemUnidade .

Table MensagemUnidade is related to the client as follows:

public class MensagemUnidade
{
    public int ClienteId { get; set; }
    public int UnidadeId { get; set; }

    public virtual Cliente Cliente { get; set; }
    public virtual Unidade Unidade { get; set; }
}

I'm using the Domain-Driven Design (DDD) model in project construction, when I try to do a search on mensagemServico it brings the message, it brings the company, and up ClienteId , but the Cliente object % comes null.

I do not know what I might have done wrong, in the table Customer has only PessoaId I added a person and then added that person to the client, if I search for that PessoaId it returns a Cliente but it does not bring up when I look for message.

My class Cliente has no connection class (Ex Unit) but my unit class has Coleção de Clientes .

If someone can help me, I'll be extremely grateful if they lack information and just let me know.

In the context this contains the following line in method onModelCreating :

 Configuration.LazyLoadingEnabled = true;

In the example I followed in OnModelCreating of Contexto is using a code similar to that

 modelBuilder.Entity<ClienteLoja>().HasRequired(v => v.Loja).WithMany(m => m.Clientes).HasForeignKey(f => f.LojaId);

I did not put anything like this in my code, is it necessary? if so why?

EDIT: This is the search I do:

 List<MensagemUnidade> mensagens = this.mensagemServico.GetMany(l => l.UnidadeId == unidade.UnidadeAtual && l.OrigemId == (int)enumOrigemMensagem.USUARIO).OrderByDescending(l => l.DataEnvio).Skip(mensagemModel.PaginaAtual * 20).Take(20).ToList();

EDIT 2: This is the method that I use as getMany, there was a previous project here and I need to make a new one and I'm using this previous base, in a similar search it brings the required information even without the include or something of that, everything else this is the same as my code except in the context that I have nothing of the type:

 modelBuilder.Entity<ClienteLoja>().HasRequired(v => v.Loja).WithMany(m => m.Clientes).HasForeignKey(f => f.LojaId);

this is my getMany method:

public virtual IQueryable<T> GetMany(Expression<Func<T, bool>> where)
    {
        return dbset.Where(where);
    }
    
asked by anonymous 03.11.2016 / 13:11

2 answers

3

With LazyLoad you can access the property Cliente content needs that contexto is still alive.

If you want to access the Cliente property then you will have to Eager load. In your case this is the ideal solution to avoid the problem of N + 1

As @Guilherme de Jesus Santos indicated you can use Include . To use the version lambda you still need to include the namespace System.Data.Entity

using System.Data.Entity;

The end result would be:

this.mensagemServico.Include(c => c.Cliente)
    .Where(l => l.UnidadeId == unidade.UnidadeAtual && l.OrigemId == (int)enumOrigemMensagem.USUARIO)
    .OrderByDescending(l => l.DataEnvio)
    .Skip(mensagemModel.PaginaAtual * 20).Take(20).ToList();

The solution you have is to change your class mensagemServico . In fact, its GetMany method can not even make much sense. I suggested you implement one method per query / process. If this implies many changes in your code at this time leave the GetMany where it is.

For example for this case you would create the following method:

public IEnumerable<MensagemUnidade> GetMensagensDoUsuario(int unidade, int pagina)
{
     return dbset.Include(c => c.Cliente)
        .Where(l => l.UnidadeId == unidade && l.OrigemId == (int)enumOrigemMensagem.USUARIO)
        .OrderByDescending(l => l.DataEnvio)
        .Skip(pagina * 20).Take(20).ToList();
}
    
03.11.2016 / 13:47
2

Since you are using EntityFrameWork, I believe you need to append the Include clause when you search the Mensagem entity.

By the way today you should be doing something like this:

   var query = from msg in db.MensagemUnidade
            select msg;

In this case, because of the Lazy Loading , the Client entity will not be loaded.

Then change the query to

 var query = from msg in db.MensagemUnidade.Include(c => c.Cliente)
            select msg;

In this way the Client entity is loaded.

This article also explains the behavior: link

    
03.11.2016 / 13:28