Entity Framework Core 2 - Recursive search in many-to-many relationships

0

I made a many-to-many relationship using EF Core 2, Code First method. > in this link , you need 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; }
}

Defining relationships in 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);
}

Entity created, I include it:

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 tested in MySQL and SQlite.

Inclusion works perfectly by creating the tables and relationships, but the search is valuing the CustomerServices object of the last Client entity, which in turn also has a Client object inside it, which also has a ServersService entity, in turn:

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

    
asked by anonymous 05.09.2018 / 01:08

1 answer

0

Well, according to this post , this seems to be an EF Core 2 standard and the correct one is to use DTO + Projection. Using the tutorial link , I have developed the following:

DTO class with a list of service names:

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();
    
05.09.2018 / 02:13