none
Deletando com o entity framework RRS feed

  • Pergunta

  • fala ae galera..

    bom, estou com um problema ..

    imagine que temos uma classe com uma coleção imensa de itens... EXEMPLO:

    Cliente
       -> ListaDeCompras

    agora imaginem que eu precise excluir o cliente e limpar todas as ocorrencias de compras ja efetuada pelo mesmo... como faria?

    bom, em todos os artigos eles pedem para fazer isso:

    -----------------------------------------------------------------------------------------------------

    Cliente cliente = Model.ClienteSet.Where(f=>f.id=1).FirstOrDefault();
    cliente.ListaDeCompras.Load();

    foreach(Compra compra in cliente.ListaDeCompras)
       cliente.ListaDeCompras.Remove(compra);

    Model.DeleteObject(cliente);
    Model.SaveChanges();

    -----------------------------------------------------------------------------------------------------

    Vejam a perca de performance e a ida desnecessária ao banco de dados... essa minha coleção deve passar de 1000 itens facil facil... e é provavem que cada item tenha um ou dois campos text bem grandes... ou seja... q locura é essa que inventaram que não me deixa excluir esses itens de forma performatica??

    Alguem ae sabe como resolver isso?

    vlww abs 

    Ozzyvegeta
    segunda-feira, 5 de outubro de 2009 07:45

Respostas

  • Ozzy como é bom responder perguntas no fórum, estudei pra prova de ADO faz um mês, apenas estudei o entity framework nunca trabalhei com ele, foi apenas um capítulo do livro, então bem superficial, fui fazer o teste e adivinha não aparecia a função também, então fui e coloquei o return como uma entidade qualquer, no meu caso Documentos, compilei e... la estava a função!!!
    O porque disso? Cara não sei te responder, mas uma coisa eu garanto a função estará la e funcionando.
    O engraçado, você tem mil tipos para retornar porém só vai funcionar se você colocar uma entidade, não adianta int, nem single.
    Pesquisarei o porque disso, não agora está meio tarde hjahahaha, e posto aqui, pelo menos você terá a função agora também.
    • Marcado como Resposta Ozzyvegeta terça-feira, 13 de outubro de 2009 05:45
    terça-feira, 13 de outubro de 2009 04:59

Todas as Respostas

  • Ozzyvegeta,

    Porque você não cria uma procedure na base e faz o mapeamento da mesma no modelo?

    Att.

    Ari C. Raimundo
    segunda-feira, 5 de outubro de 2009 13:39
  • fala Ari,

    Soluções existem de monte para o meu problema, porem eu imagino que uma ferramenta desse porte deva ter esse tipo de opção nativamente. Do contrario fica dificil pois eu já estou delegando ao EF toda a minha camada de acesso a dados, preciso confiança no mesmo para fazer o minimo que é o CRUD.

    Vlw



    Ozzyvegeta
    segunda-feira, 5 de outubro de 2009 15:03
  • Ozzy,

    Acho que a melhor opção é a stored procedure mesmo. Talvez os outros colegas do fórum tenham outra opinião.

    Att.

    Ari C. Raimundo
    segunda-feira, 5 de outubro de 2009 15:36
  • fala ari...

    como disse amigo... é uma boa opção, porem oq estou procurando é algo no EF... ele é muito bom para pesquisas e facilidade para se criar as entidades rapidamente.. porem quando se precisa de um trabalho AVANÇADO ele PRA MIM esta deixando a desejar... com entidades simples ele consegue funcionar bem.. até o Attach funciona bem com entidades simples rs... porem quando se poe uma coleção, uma entidade com mais d um nivel de relacionamento...ele se perde e não funciona.. ai a opção é encher o codigo de códigos de infra para supri oq ele não faz nativamente...

    bom, estou torçendo d+ pra proxima versão do EF.. pq essa ta equivalente ao LinqToSQL, limitada e pra projetos basicos...



    vlw

    Ozzyvegeta
    segunda-feira, 5 de outubro de 2009 15:48
  • No seu .edmx clique com o botão direito e abrir com... selecione o edito xml

    Aqui um exemplo de como estava o meu:

    <Association Name="FK_Product_ProductType">
              <End Role="ProductType" Type="VideoGamesModel.ProductType" Multiplicity="1" />
              <End Role="Product" Type="VideoGamesModel.Product" Multiplicity="*" />
            </Association>
    E de como deixei para resoler o problema:

    <Association Name="FK_Product_ProductType">
              <End Role="ProductType" Type="VideoGamesModel.ProductType" Multiplicity="1">
                <OnDelete Action="Cascade"></OnDelete>
              </End>
              <End Role="Product" Type="VideoGamesModel.Product" Multiplicity="*" />
            </Association>
    Fique atento você tem que atualizar o ssdl e o csdl, você terá acesso aos dois de uma vez no hora que abrir como xml.
    terça-feira, 6 de outubro de 2009 04:18
  • Ari, vc pode me mandar um exemplo de como utilizar procedure.. eu fiz mais a procedure não apareceu no context e nem em lugar algum..

    meu email é : EMAIL REMOVED

    vlww ae


    Ozzyvegeta
    sexta-feira, 9 de outubro de 2009 19:41
  • Ozzyvegeta não deu certo adicionando o OnDelete?
    sexta-feira, 9 de outubro de 2009 19:42
  • cara, na verdade eu precisaria excluir o relacionamento mesmo. Pois estou adotando a metodologia de quando eu fizer o update em uma determinada entidade eu excluo todas as coleções e salvo todas novamente com begin transaction... e por isso não testei o OnDelete... pq é um update .. exemplo:

    public static Update(Usuario usuarioRef)
    {
       using (var meuBancoEntities db = new meuBancoEntities())
       {
           var usuarioEdit = db.GetById<Usuario>(usuarioRef.IdUsuario);
           usuarioEdit = ReflectionHelper.CopyEntity(usuarioRef, usuarioEdit) // Meu helper para copiar tudo de ref para o edit.
      
           try
           {
                context.Connection.BeginTransaction()
                context.DeletarGrupos(usuarioEdit.IdUsuario); // Aqui eu deletarei toda a relação utilizando SP já que o EF não da suporte para isso.
                context.DeletarOutraColecao(usuarioEdit.IdUsuario); // Mesma coisa
                context.SaveChanges();
                context.Commit();
           }
           cacth (Exception ex)
           {
                 context.Connection.RollBack();
            }
       }
    }


    Esta tudo funcionando legal, porem os metodos de delatar estão vazios pois não sei como implementa-los...

    vlww
    Ozzyvegeta
    sexta-feira, 9 de outubro de 2009 19:56
  • Entendi mas se você adicionar o OnDelete no seu ssdl e csdl ai é só você deletar SP que os outros serão deletados automaticamente, não precisando fazer duas funções para isso, e ta,bém você faria isso dento do transaction. Bom esse é meu ponto de vista, provavelmente você tem motivos para fazer isso. Só um detalhe se for testar, lembre que você terá que adicionar o OnDelete em todas relações um para n tanto do ssdl quanto csdl.
    Caso ache outra maneira poste ai.
    Valeu
    sexta-feira, 9 de outubro de 2009 20:11
  • então, não posso deletar a entidade Usuario pois ela tem forenkeys com outras tabelas e ai eu teria exceção gerada da base de dados. Agora eu apagando somente as agregações eu não teria esse problema e fora que seria semantico. Apagando Usuario seria uma gambi que daria certo caso não holvesse as forenkehys..

    Vc já conseguiu utilizar SP com EF cara? em alguns artigos eu vejo que é possivel em outros que não é... to confuso...

    e uma pergunta a todos... vamos supor que vcs tivesse esse cenario que descrevi... como vcs resolveriam...?? sei que a solução depende inclsuve da arquitetura, eu optei por utilizar o Context de forma desconectada. mais isso foi uma opção minha já que não sei como utiliza-lo de outra forma em projetos Web (sem ferir as camadas).

    ?

    Acho que uma discução sobre isso iria ajudar a todos.

    Vlw
    Ozzyvegeta
    sexta-feira, 9 de outubro de 2009 20:43
  • Ozzy,

    Segue alguns links abaixo:

    Stored Procedure Support (Entity Framework)
    http://msdn.microsoft.com/en-us/library/bb399203.aspx

    How to: define a Model with Modification Stored Procedures (Entity Framework)
    http://msdn.microsoft.com/en-us/library/cc716731.aspx

    Att.

    Ari C. Raimundo
    sábado, 10 de outubro de 2009 02:37
  • Só complementando os bons artigos de Ari, para facilitar usando import visual.
    Após você ter criado suas entidades, faça assim:

    1) Clique em cima do model no solution explorer e va em Model Browser
    2) Na pasta stored procedure botão direito e update model from database
    3) Na tela que aparece selecione as stored
    4) Botão direito no model browser procedure e add -> function import
    5) Escolha a stored procedure e de um nome, esse nome irá aparecer em seu código. Escolha o tipo de retorno (None, scalar ou entidade)
    6) Use a stored da seguinte maneira:

    Entities en = new Entities();
    en.NomeDaFuncao(parametros);
    sábado, 10 de outubro de 2009 07:24
  • bom... vamos por partes...

    oq estou querendo é fazer isso via Interface grafica... os artigos do Ari não mostram em nenhum momento esse tipo de coisa... apenas mostra como fazer para inserir uma procedure no xml do EF... e detalhe.: ele não mostra como mapear esse metodo no codigo c#...

    Murilo.. eu fiz exatamente isso q vc fez e não consegui fazer funcionar cara... o metodo não aparece no código fonte c#... no xml do EF ele aparece, porem já salvei, buldei...fiz d td e ele não aperece no código fonte c#.... sera q as procedures tem q ter algum "SET XXX ON" no SQL SERVER, seu lá... no meu caso estou usando MYSQL e SQL SERVER como bancos... mais fazendo funcionar em um eu procuro a solução em outro...

    vlww
    Ozzyvegeta
    terça-feira, 13 de outubro de 2009 00:01
  • Onde você está procurando pelo nome da função?
    Ela estará na context ou seja na parte que trata as conexões e o mapeiamento dos dados, e não na tabela. Por exemplo na hra que gerou o EDM você deu o nome de Model.edmx e no mapeiamento como Entidades, com as tabelas Pessoa e ComprasPessoa por exemplo.
    Então você fará:

    Entidades entidades = new Entdades();

    Sua stored procedure estará em entidades.NomeDaFuncao(parametros) e não nas tabelas como entidades.Pessoa.NomeDaFuncao();

    Outra coisa certifique que você foi em add -> function import e  não no mapeamento de stored procedure para determinada tabela, para ter certeza disso no momento que clicar com o botão direito nao clique em cima de nenhuma tabela. A diferença entre as duas é que uma você chamará a stored pra determinada função e a outra (mapeamento para tabela) é que quando você fizer um addToPessoa() ela usará a stored procedure para salvar no banco quando você der o UpdateChanges

    terça-feira, 13 de outubro de 2009 02:40
  • fala Murilo...

    pois é amigo..estou fazendo td isso q vc disse..exatamente os mesmos caminhs... ele simplesmente não gera a função no "model1.designer.cs"... que seria o context...

    c quiser t mando um exemplo pra vc ver...

    e soh pra definir... estou usando o esquema de "procedure para função no context" e não o esquema d crud por entidade...

    sera que tem haver com versões, ou algo do tipo?

    flw
    Ozzyvegeta
    terça-feira, 13 de outubro de 2009 03:38
  • Ozzy como é bom responder perguntas no fórum, estudei pra prova de ADO faz um mês, apenas estudei o entity framework nunca trabalhei com ele, foi apenas um capítulo do livro, então bem superficial, fui fazer o teste e adivinha não aparecia a função também, então fui e coloquei o return como uma entidade qualquer, no meu caso Documentos, compilei e... la estava a função!!!
    O porque disso? Cara não sei te responder, mas uma coisa eu garanto a função estará la e funcionando.
    O engraçado, você tem mil tipos para retornar porém só vai funcionar se você colocar uma entidade, não adianta int, nem single.
    Pesquisarei o porque disso, não agora está meio tarde hjahahaha, e posto aqui, pelo menos você terá a função agora também.
    • Marcado como Resposta Ozzyvegeta terça-feira, 13 de outubro de 2009 05:45
    terça-feira, 13 de outubro de 2009 04:59
  • grande Murilo...

    vc fez o unico teste q eu não fiz...testar adicionado um return de uma referencia do model... eu tentei colocar um int, double outros e nada da função aparecer...mais colocando uma entidade ai funcionou pra mim tb...

    tai um bug do EF... to pensando em criar uma entidade qualquer apenas para return e deixar ai como gambi msm ... quando eu axa a solução eu melhoro isso rsrs

    mais vlw ae cara... c vc axa a solução posta ai tb...

    vlww
    Ozzyvegeta
    terça-feira, 13 de outubro de 2009 05:11
  • Bom pelo jeito acho que é bug mesmo, veja isso:

    http://forums.asp.net/t/1363046.aspx
    terça-feira, 13 de outubro de 2009 05:19
  • eh... parece q o povo estava revoltado nesse post rs..
    mais realmente.. o EF é beta com ctrz...muitas das coisas n funcionam legal ainda...

    mais msm assim eu estou insistindo nele...

    uma solução para esse problema da procedure foi utilizar o EFExtension... no post a mulher cita ele tb...

    eu estou usando ele e fiz uma adaptação nele para trabalhar com transactions, oq nativamente ele não faz... fico legal...

    agora eu posso fazer qualquer comando na base sem precisar passar pelo EF... delete e updates avontade e com transaction  (uffa) rsrs

    mais vlw esse post... vou acinar como resposta ... vlw murilo
    Ozzyvegeta
    terça-feira, 13 de outubro de 2009 05:45