Array
(
    [0] => stdClass Object
        (
            [Votos_Balanceados] => 1
            [id] => 541108
            [titulo] => API - problemas com await e async
            [dataCadastro] => DateTime Object
                (
                    [date] => 2015-12-30 15:36:33
                    [timezone_type] => 3
                    [timezone] => America/Sao_Paulo
                )

            [isFirstPost] => -1
            [idUsuario] => 418027
            [status] => A
            [isExample] => 
            [NomeUsuario] => Jothaz
            [Apelido] => 
            [Foto] => 418027_20150313165406.jpg
            [Conteudo] => 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. ) )

API - problemas com await e async

Hard Shop
|
MVP
    30 dez 2015

Seguindo este material: Integrando aplicações com Web API Parte 1
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:
#Código

// 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():
#Código
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?

Post mais votado

Jothaz
   - 30 dez 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.

Hard Shop
|
MVP
    30 dez 2015

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.
:/

Jothaz
   - 30 dez 2015

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
.

Hard Shop
|
MVP
    30 dez 2015

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.

Jothaz
   - 30 dez 2015

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.