Entity Framework Core 2 - Recursive research into many-to-many relationships

Asked

Viewed 71 times

0

I made a many-to-many relationship using EF Core 2, Code First method. Second seen at that link, it is necessary to create a Join entity:

public class ClienteModel
{
    public int ClienteId { get; set; }
    public string NomeEmpresa { get; set; }
    public string NomeContato { get; set; }
    public string Telefone { get; set; }
    public string Email { get; set; }
    public string ConteudoConversa { get; set; }
    public DateTime DataHoraConversa { get; set; }
    public List<ClienteServicoModel> ClienteServico { get; set; }
}

public class ServicoModel
{
    public int ServicoId { get; set; }
    public string NomeServico { get; set; }
    public List<ClienteServicoModel> ClienteServico { get; set; }
}

public class ClienteServicoModel
{
    public int ClienteId { get; set; }
    public ClienteModel Cliente { get; set; }
    public int ServicoId { get; set; }
    public ServicoModel Servico { get; set; }
}

Definition of relations in the context:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<ClienteModel>().HasKey(m => m.ClienteId);
    modelBuilder.Entity<ServicoModel>().HasKey(m => m.ServicoId);
    modelBuilder.Entity<ClienteServicoModel>().HasKey(m => new { m.ClienteId, m.ServicoId });
    modelBuilder.Entity<ClienteServicoModel>().HasOne(m => m.Cliente).WithMany(e => e.ClienteServico).HasForeignKey(m => m.ClienteId);
    modelBuilder.Entity<ClienteServicoModel>().HasOne(m => m.Servico).WithMany(e => e.ClienteServico).HasForeignKey(m => m.ServicoId);
    base.OnModelCreating(modelBuilder);
}

Created entity, I do the inclusion:

public ActionResult<IEnumerable<ClienteModel>> Post(ClienteModel Cliente)
{
    var clienteServico1 = new ClienteServicoModel();
    var clienteServico2 = new ClienteServicoModel();
    var cliente = new ClienteModel()
    {
        NomeEmpresa = "Teste",
        NomeContato = "Teste",
        Telefone = "Teste",
        Email = "Teste",
        ConteudoConversa = "Teste",
        DataHoraConversa = DateTime.Now
    };

    var servico1 = new ServicoModel()
    {
        NomeServico = "Teste 1"
    };

    var servico2 = new ServicoModel()
    {
        NomeServico = "Teste 2"
    };

    clienteServico1.Cliente = cliente;
    clienteServico1.Servico = servico1;

    clienteServico2.Cliente = cliente;
    clienteServico2.Servico = servico2;

    cliente.ClienteServico = new List<ClienteServicoModel>();
    cliente.ClienteServico.Add(clienteServico1);
    cliente.ClienteServico.Add(clienteServico2);

    _context.Clientes.Add(cliente);
    _context.Servicos.Add(servico1);
    _context.Servicos.Add(servico2);

    _context.SaveChanges();

    return _context.Clientes.ToList();
}

I did the test in Mysql and Sqlite.

The inclusion works perfectly, creating the tables and relationships, but the research is valuing the Clientesservicos object of the last Client entity, which in turn also has a Client object within it, which also has a Clientesservicos entity, so successively:

inserir a descrição da imagem aqui

inserir a descrição da imagem aqui

What is wrong with the code or how to make only the first level of Join entity valued in the search?

  • They are two different objects, the object with ClienteId 1 has a list of ClientesServiço?

  • @Barbetta yes, the two objects were valued equally, in theory, if the last turn valued Clienteservice, the first should also return

1 answer

0

Well, according to that post, this seems to be a pattern of EF Core 2 and the correct is to use DTO + Projection. Using the tutorial at that link, I developed the following:

DTO class with a service name list:

public class ClienteDto
{
    public int ClienteId { get; set; }
    public string NomeEmpresa { get; set; }
    public string NomeContato { get; set; }
    public string Telefone { get; set; }
    public string Email { get; set; }
    public string ConteudoConversa { get; set; }
    public DateTime DataHoraConversa { get; set; }
    public List<string> NomeServico { get; set; }
}

Controller Change:

return _context.Clientes.Select(x => new ClienteDto()
        {
            ClienteId = x.ClienteId, 
            NomeEmpresa = x.NomeEmpresa, 
            NomeContato = x.NomeContato, 
            Telefone = x.Telefone, 
            Email = x.Email, 
            ConteudoConversa = x.ConteudoConversa, 
            DataHoraConversa = x.DataHoraConversa,
            NomeServico = x.ClienteServico.Select(c => c.Servico.NomeServico).ToList()
        }).ToList();

Browser other questions tagged

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