API - problemas com await e async

30/12/2015

0

Seguindo este material: [url:descricao=Integrando aplicações com Web API Parte 1]https://www.devmedia.com.br/integrando-aplicacoes-com-web-api-parte-1/32821#[/url]
Desenvolvi uma API que faz um POST de itens no banco de dados, mas antes eu preciso definir uma ID que seja única para o item, então criei um método GetMaiorCod() que retorna um Task<decimal> com o maior ID do bd e incrementa 1.
O que está acontecendo é que quando eu mando item por item, grava no bd corretamente com a ID única, mas quando mando uma array com vários itens ocorre 'conflict', deve estar pegando o GetMaiorCod() mais de uma vez e logo em seguida gravando no bd.
-----------------------
Este é o POST:

// POST: api/Itemprevendas
        [ResponseType(typeof(Itemprevenda))]
        public async Task<IHttpActionResult> PostItemprevenda(Itemprevenda itemprevenda)
        {

            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            //  Implementar o id.
            decimal cd = await GetMaiorCod();
            itemprevenda.Cditemprevenda = cd;

            db.Itemprevenda.Add(itemprevenda);

            try
            {
                await db.SaveChangesAsync();
            }
            catch (DbUpdateException)
            {
                if (ItemprevendaExists(itemprevenda.Cditemprevenda))
                {
                    return Conflict();
                }
                else
                {
                    throw;
                }
            }


-----------------------------
Este é o GetMaiorCod():

public async Task<decimal> GetMaiorCod()
        {
            Itemprevenda itemprevenda = await db.Itemprevenda.FindAsync(1);
            if (itemprevenda == null)
            {
                return 1;
            }

            decimal GetTeste = 0;
            var itemQuery =
                from Itemprevenda in db.Itemprevenda
                group Itemprevenda by Itemprevenda.Cditemprevenda into grouping
                select new
                {
                    grouping.Key,
                    maiorCod =
                    from Itemprevenda in grouping
                    where Itemprevenda.Cditemprevenda == grouping.Max(Itemprevenda1 =>
                    Itemprevenda1.Cditemprevenda)
                    select Itemprevenda
                };
            foreach (var item in itemQuery)
            {
                foreach (var listing in item.maiorCod)
                {
                    GetTeste = (listing.Cditemprevenda + 1);
                }
            }
            return GetTeste;
        }


O que posso fazer para que um item aguarde o outro ser gravado no bd para depois pegar seu ID?
Hard Shop

Hard Shop

Responder

Post mais votado

30/12/2015

Já pensou em definir o campo ID da tabela como auto-incremento.
Assim o banco de dados garante que a cada INSERT seja gerado um número único e você não precisa se preocupar com isto.

Jothaz

Jothaz
Responder

Mais Posts

30/12/2015

Hard Shop

Seria interessante, mas este banco de dados já está sendo usado em um sistema desktop e já tem um formato definido, não posso fazer alterações no banco.
Só posso trabalhar com a API.
:/
Responder

30/12/2015

Jothaz

Entendo bem esta maldição dos legados! kkk

É muito difícil sugerir algo com somente códigos e sem um visão mais completa do cenário e estrutura de dados. E sem poder testar.

Vou arriscar mais uma sugestão e espero não esta falando bobagens se estiver favor desconsidere a sugestão.

Tente separar a execução dos métodos assim:
1-Pegue o array de itens e criei o campo MaiorCod nele;
2-Execute o método GetMaiorCod para todos o itens do array e preencha o campo MaiorCod e
3- Posteriormente execute db.SaveChanges
.
Responder

30/12/2015

Hard Shop

Até então eu usava esta solução que você propôs, até identificar o seguinte problema.
Quando estou pegando o maior código em mais de um sistema por vez ele vai trazer o mesmo código para os dois.
Exemplo: no aplicativo eu busco o maior código que é 5, ao mesmo tempo no sistema desktop buscou o mesmo maior código 5, vai dar conflito na gravação. Apesar de ser algo quase impossível de acontecer, pode acontecer :(
Este controle precisa ser feito diretamente na API onde grava o dado.
Responder

30/12/2015

Jothaz

Olha só não sei se aplica ao seu problema, mas sou das antigas trabalho com desenvolvimento desde eras priscas.

Neste tempo não tínhamos as facilidades de hoje,então para definir um sequencial criávamos uma tabela onde existia somente um campo e um registro com o último ID gravado, então era só ler esta tabela pegar o valor, somar 1, gravar o valor somado e usá-lo como ID.

Sei que parece uma gambiarra, mas talvez lhe ajude e funcionar. E pode simplificar sua vida.

Realmente é bem complicado fazer com que a execução dos método obedeça a um ordem. Afinal ao usar certas facilidades você não tem muito controle sobre o fluxo.

Mas vamos esperar se alguém tem alguma sugestão.
Responder

Assista grátis a nossa aula inaugural

Assitir aula

Saiba por que programar é uma questão de
sobrevivência e como aprender sem riscos

Assistir agora

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar