Inheritance problem

Asked

Viewed 220 times

3

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

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

The Table MensagemUnidade has customer relationship 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 am using the DDD(Domain-Driven Design) model in project construction, when I try to do a research on mensagemServico he brings the message, brings the company, and even the ClienteId , but the object Cliente comes void.

I don’t know what I might have done wrong, on the table Client only has the PessoaId I added a person and then added that person to the customer, if I search for that person PessoaId he returns a Cliente, but it does not bring when seeking message.

My Class Cliente does not have any connection class (Ex Unit) but my unit class has a Coleção de Clientes.

If anyone can help me I will be extremely grateful, if information is missing and only and warn.

In the context this contains the following line in the 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 didn’t put anything like this in my code, is it necessary? if yes why?

EDIT: This is the research 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 I use as getMany, there was a previous project here and I need to make a new one and I am using this previous base, in a similar search it brings the necessary information even without the include or something like, everything else is the same as my code except in the context that I have nothing of the kind:

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

this and my getMany method:

public virtual IQueryable<T> GetMany(Expression<Func<T, bool>> where)
    {
        return dbset.Where(where);
    }
  • 1

    GetMany()? You have how to post the implementation of this method?

  • 2

    @Williamcézar, advice, give up the RU or the DDD, I would particularly like to keep the EF ;D

  • @Tobymosque I would say that they are not mutually exclusive, just have to do things so that they are minimally organized.

  • I’m looking for content to try to understand how it works, but it’s very complicated, the rest is all working as it should, I think I’ll leave a custom call in the service where you have include and add the customer, as I have 2 layers that need access to the database , Api and Web ,I use the DDD , to be able to have a semparação of the layers.

  • 1

    @Brunocosta is possible, but the overhead will take hours of development, your code will not be easier to maintain, you will create artificial limitations to the EF and you will hardly have gained readability. So if there is no gain of Maintainability, Readability, Performance or Time, pq make use of an approach of this?

  • One more: http://answall.com/questions/51536/quando-usar-entity-framework-com-repository-pattern/80696#80696

  • @Brunocosta are almost. Can be considered an anti-standard. I explain here.

  • @Tobymosque Everything depends on what you mean by ddd maybe I understand ddd in a different way than yours. It takes hours of development depends only on the abstraction you are creating. I’ve seen that answer and I agree with it. If you want to come to a chat and we have a conversation Xp

Show 3 more comments

2 answers

3


With the LazyLoad Voce can access the property Cliente content requires that the contexto is still alive.

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

As @Guilherme de Jesus Santos indicated Voce can use the Include. To use the version lambda Voce also needs 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 Voce has is to change its class mensagemServico. In fact your method GetMany may not even make much sense. I suggested Voce implement a method for each query/process. If this implies many changes in your code at this time let the GetMany where he is.

For example for this case Voce 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();
}
  • Even adding System.Data.Entity o . include() is not recognized.

  • @Williamcézar I see that mensagemServico is not a DbSet . Do this about the DbSet context. Example: contexto.MensagemUnidade.Include

  • 1

    @Williamcézar you are using the "default" DDD. Logo, mensagemServico is a means to access the DbSet, so there is no include.

  • @Williamcézar This one of the dozens of problems of using the DDD standard. Can you see that it only makes things worse (at least in this case)? You’re confusing everything... I bet you have no idea why you’re using this pattern.

  • Why is it necessary?

  • You have how to read my comment on the question and add the details I asked?

  • @jbueno It’s true I don’t think the AP has the code well organized

  • I understood a little more, in case it was necessary in the messaging service I could make a custom getmany that added the Customer. See my comment in the main about the structure, if not to follow the DDD what other project options ? has some article for me to follow ?

  • @Williamcézar I do not want to be searching on the internet. But I can tell you who will find many but many ways different to do. Most of them are correct or make sense, others not so much. You have to find one that works for you. If you need to see examples you have to wait for someone else to tell you, or look for yourself.

  • I understood what you meant , now it makes more sense, this getMany and a method that is in Baseservico, in case all my services possess it, thank you very much for the patience I will inform better.

Show 5 more comments

2

Since you are using Entityframework, I believe you need to add the clause Includewhen you search the entity Mensagem.

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

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

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

Then change the query to

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

This way the Client entity is loaded.

This article also explains the behavior : https://ferhenriquef.com/2012/03/19/uso-de-include-em-consultas-com-o-entity-framework-code-first/

  • por causa do conceito de Lazy Loading, o entidade Cliente não será carregada. On the contrary, for having Lazy Loading the entity Cliente can be carried, but only if the code accesses it

Browser other questions tagged

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