SUM within SUM Entity Framework performance

Asked

Viewed 790 times

0

I made a query with Entity framework and I’m having problems with performance.

 public static Decimal ValorPrevisto(this ClinicaModel clinica)
        {
            return clinica.Contratos.Sum(c => c.Mensalidades.Where(m => m.Pagamento != null).Sum(t => t.Valor)) / 2;
        }

This code is taking more than 3 minutes to run as it is scanning record by record, searched several times and did not find a way to improve performance.

Classe Clinicamodel

public class ClinicaModel : Base.BaseModel
    {
        public string Nome { get; set; }
        public DateTime HoraExpedienteInicio { get; set; }
        public DateTime HoraExpedienteTermino { get; set; }
        public int DuracaoConsulta { get; set; }
        public int DiasExpediente { get; set; }
        public string Email { get; set; }
        public virtual EnderecoModel Endereco { get; set; }
        public virtual ContatoModel Telefone { get; set; }
        public virtual PessoaFisicaModel Responsavel { get; set; }
        public virtual ICollection<UsuarioModel> Usuarios { get; set; }
        public virtual ICollection<DoutorModel> Doutores { get; set; }
        public virtual ICollection<ConvenioModel> Convenios { get; set; }
        public virtual ICollection<ContratoModel> Contratos { get; set; }
        public virtual ICollection<PagamentoModel> Pagamentos { get; set; }
        public ClinicaModel()
        {
            Usuarios = new HashSet<UsuarioModel>();
            Doutores = new HashSet<DoutorModel>();
            Convenios = new HashSet<ConvenioModel>();
            Pagamentos = new HashSet<PagamentoModel>();
            Contratos = new HashSet<ContratoModel>();

        }

        public override string ToString()
        {
            return Nome;
        }
    }
  • 3

    This code certainly does not take a millisecond, after all it only assembles the expression and does not query any. LINQ does not work as people imagine. It may be taking a while elsewhere. Anyway only with this code it is not possible to say where the problem may be. It can be even in the database. There is no miracle, a sum of a large number of lines where index cannot be used and if the database has no means of optimization, it will be slow even. This code does not indicate anything that can be optimized there.

  • it happens that I run this query in the sql database and it doesn’t take long, just there, because in the query it seems q it scans record by record instead of making a calculation only.

  • clinical. Contract what class is this? could show the Clinicamodel class?

  • Ready Edited!

1 answer

2


If I’m not mistaken, navigation properties, outside the Iqueryable context are loaded in memory using Lazy load.

In your case, being sum the sum, would return several queries to the bank, as you are probably not using Iqueryable.

I know Voce created this property in order to return the value with a single query, but I think it is not possible because Voce is outside the Context. It is possible to use directly from the context, as this will be possible, because Ocean will work with Dbset iqueryable clincas. Test the following outside the scope of the property and see if performance increases, so Voce will understand the problem:

 var context = new MyContext();// nao sei qual o nome do seu context de entitdades
 var clinicaId = 1;// ponha o Id de teste aqui

 var valorPrevistoClinca = context.ClinicaModel.Where(c=> c.Id = clinicaId).SelectMany(c=> c.Mensalidades.Where(m=> m.Pagamento != null)).Sum(m=> m.Valor) / 2;

Swirled?

  • the problem is that I’m using layers, and the context is outside the view layer..., but I think I understand the problem, because when I debug it performs several queries going through the record by record!

  • yes, I imagined this, so in this case,I think it best to create another class so that the view consumes, where Voce can consult the expected value, provided as argument the clinic or her id.

Browser other questions tagged

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