Exportar (0) Imprimir
Expandir Tudo

Manutenção de Dados no Entity Framework 4

Por Renato Haddad

Maio, 2012

JJ128160.060DE5057573180CEC6D227C6D3E2207(pt-br,MSDN.10).png

Introdução

Neste artigo irei abordar a manutenção de registros no Entity Framework 4, tecnologia que é um marco para o modelo de objeto relacional no .NET. O EF 4 é baseado no modelo de classes gerado a partir de um banco de dados ou a partir de um conjunto de classes usando o POCO (Plain Old CLR Object) (http://msdn.microsoft.com/pt-br/library/ff978717.aspx), mas isto não é o foco agora.

EDM (Entity Data Model)

O EDM que foi idealizado nos módulos anteriores deste MVA é o que está representado na figura a seguir, o qual há duas entidades relacionadas, grupo e produto. Observe que há um relacionamento de um grupo para vários produtos (um para muitos), sendo que a chave é o Id e o IdGrupo.

JJ128160.67C10406961F550DCF05242E5AB90713(pt-br,MSDN.10).png

Criar um EDM coeso é o ponto chave de qualquer aplicação, implicando em diversos fatores como manutenção, facilidade de entendimento e programação, padronização de código e extensibilidade. Para ilustrar a manutenção de dados criei um projeto de Console, assim podemos focar diretamente no EF 4. Este projeto tem o Program.cs com o método estático Main.

class Program
{
    static void Main(string[] args)
    {
    }
}

Para exibir todos os dados do banco de dados, adicione neste Main a chamada do método MostraDados. Como ele não existe, ao digitar o método, o Visual Studio irá ilustrar um erro. Em seguida pressione CTRL + . (ponto) e ENTER para criar o método.

MostraDados();

Usei o Using para instanciar o objeto MVA_EF4Entities que contém todas as classes do EDM. Em seguida, o foreach irá ler todos os grupos contidos na entidade Grupo para ler cada item. Note que usei uma expressão Lambda OrderBy para classificar os dados pela propriedade Nome. Para cada item lido são mostradas as propriedades Id e Nome. Em seguida, criei um looping foreach para exibir todos os produtos contidos na entidade Produto.

private static void MostraDados()
{
    using (var ctx = new MVA_EF4Entities())
    {
        foreach (var g in ctx.Grupo.OrderBy(g => g.Nome))
        {
            Console.WriteLine(g.Id + " - " +
                                g.Nome);
        }

        Console.WriteLine("===== Produtos =====");
        foreach (var p in ctx.Produto)
        {
            Console.WriteLine(
                string.Format("{0} - {1} - custo: {2:n2} - venda: {3:n} - saldo: {4}",
                                p.Grupo.Nome,
                                p.Nome,
                                p.Custo,
                                p.Venda,
                                p.Saldo));
        }

        Console.ReadLine();
    }
}

Incluir Dados

Para quem usa instrução INSERT do T-SQL (transact SQL) ficará surpreso que no EF 4 não se escreve nenhuma linha de código T-SQL. A inclusão de dados no EF4 consiste basicamente em montar o objeto a ser inserido, incluir este objeto no contexto e chamar o método para efetivar a inclusão. Veja um exemplo do método IncluirDados.

private static void IncluirDados()
{
    using (var ctx = new MVA_EF4Entities())
    {
        var g = new Grupo { Nome = "Bebidas" };

        //ctx.AddObject("Grupo", g);
        ctx.AddToGrupo(g);

        // add produto
        var p = new Produto
        {
            IdGrupo = 1,
            Nome = "Caça palavras",
            Custo = 20,
            Venda = 50,
            Saldo = 100
        };
        ctx.AddToProduto(p);

        // efetiva os inserts
        ctx.SaveChanges();

        MostraDados();
    }
}

Veja a explicação detalhada. Antes de mais nada, o contexto a ser usado é o MVA_EF4Entities, portanto, tudo está dentro do Using.

using (var ctx = new MVA_EF4Entities());

Em seguida, é preciso montar o objeto do tipo Grupo, o qual contém a propriedade Nome com o conteúdo Bebidas. Este objeto está armazenado na variável g.

var g = new Grupo { Nome = "Bebidas" };

Em seguida é preciso preparar o objeto definido anteriormente (g) para ser adicionado ao contexto ctx do Using. Aqui você tem duas opções: ou usa o ctx.AddObject(entidade, objeto) ou usa o contexto seguido do AddEntidade que o próprio VS.NET gerou no contexto. O segundo é o mais fácil e como trata-se de um artigo deixei o primeiro comentado.

//ctx.AddObject("Grupo", g);
ctx.AddToGrupo(g);

Em seguida, é definido o objeto p que é do tipo Produto com as devidas propriedades. Veja que o objeto é adicionado ao contexto AddToProduto, ou seja, este objeto está preparado para ser inserido.

var p = new Produto
{
    IdGrupo = 1,
    Nome = "Caça palavras",
    Custo = 20,
    Venda = 50,
    Saldo = 100
};
ctx.AddToProduto(p);

A última fase é efetivar a inclusão em si no banco de dados. Neste caso, o contexto ctx invoca o método SaveChanges. Neste caso, todas as operações de insert, delete e update estão no mesmo contexto, e para executar basta invocar o SaveChanges. Não se preocupe com transações porque o EF 4 já lida com transações nativamente.

ctx.SaveChanges();

Incluir Dados Um para Muitos

A inclusão de dados do tipo um para muitos permite incluir dados do lado muitos sem ter o lado um ainda. Ou seja, se pensar numa relação pai e filho, você não precisa ter um pai para criar um filho. Na verdade, o relacionamento entre as entidades no EDM não permite isto, mas é possível definir uma estrutura dos dois objetos pai e filho e ao final, deixar o EF 4 incluir os dois de uma única vez. O código completo a seguir mostra exatamente esta situação.

private static void IncluiPaiFilho()
{
    using (var ctx = new MVA_EF4Entities())
    {
        // grupo
        var g = new Grupo { Nome = "Carros" };

        // produto
        var p = new Produto
        {
            IdGrupo = g.Id,
            Nome = "Ferrari",
            Custo = 10000,
            Venda = 50000,
            Saldo = 3
        };

        ctx.AddToProduto(p);
        ctx.AddToGrupo(g);

        ctx.SaveChanges();

        MostraDados();
    }
}

A explicação para este exemplo é de fácil entendimento. Veja que o Grupo Carros não existe no banco de dados, então, apenas defini o objeto Grupo com a propriedade Carros. Até aqui não foi incluído o carro ainda, muito menos tenho o Id gerado no banco de dados.

Mas, logo em seguida há o objeto produto definido com todas as propriedades. Cabe ressaltar que a propriedade IdGrupo é exatamente a propriedade Id do objeto Grupo (g) definido na linha anterior.

// grupo
var g = new Grupo { Nome = "Carros" };

// produto
var p = new Produto
{
    IdGrupo = g.Id,
    Nome = "Ferrari",
    Custo = 10000,
    Venda = 50000,
    Saldo = 3};

Toda a mágica acontece agora. Quando se preparam os dois objetos a serem incluídos, não importa a ordem hierárquica, pois quando ambos pertencem ao mesmo contexto. No entanto, ao salvar o contexto com o SaveChanges, o código irá executar o contexto de acordo com o EDM, ou seja, primeiro irá inserir o Grupo, gerar um Id para o mesmo, e depois será incluído o produto com o respectivo IdGrupo gerado em tempo de execução. Só isso já vale o artigo.

ctx.AddToProduto(p);
ctx.AddToGrupo(g);

ctx.SaveChanges();

Atualizar Dados

Para atualizar dados no EF 4, você pode montar um código para atualizar um conjunto de registros ou somente um específico. No exemplo a seguir, primeiro são lidos todos os produtos do contexto ctx, em seguida é feito um looping foreach para ler cada um dos produtos. Como cada produto contém a propriedade Saldo, o código p.Saldo +=1 soma uma unidade ao saldo atual. O melhor de tudo é que cada objeto neste momento internamente é colocado como modificado. Ao final, basta chamar o método SaveChanges do contexto e pronto, todas as atualizações são efetivadas na entidade.

private static void AtualizaGrupo()
{
    using (var ctx = new MVA_EF4Entities())
    {
        var dados = ctx.Produto;
        foreach (var p in dados)
        {
            Console.WriteLine(p.Nome + " - " + p.Saldo);
            p.Saldo += 1;
        }

        ctx.SaveChanges();

        Console.WriteLine("==== atualizados ====");

        foreach (var p in dados.Take(5))
        {
            Console.WriteLine(p.Nome + " - " + p.Saldo);
        }
        Console.ReadLine();
    }
}

Por outro lado, existe situação que é preciso alterar apenas um único produto. Neste caso, é preciso usar uma expressão Lambda FirstOrDefault para localizar o produto a ser alterado onde o Id é igual a 6. Claro que este valor poderá vir de uma interface do usuário. Caso o objeto exista, basta configurar os valores das propriedades a serem atualizadas, neste caso o Nome, Saldo e Venda. Por último, basta chamar o método SaveChanges para efetivar a alteração.

private static void AtualizaUmProduto()
{
    using (var ctx = new MVA_EF4Entities())
    {
        var atualiza = ctx.Produto.
                    FirstOrDefault(p => p.Id == 6);
        if (atualiza != null)
        {
            atualiza.Nome = "Arc Mouse Sensacional";
            atualiza.Saldo = 190;
            atualiza.Venda = 89;

            ctx.SaveChanges();
        }
    }
}

Excluir Dados

O processo de excluir dados é parecido com as rotinas de atualizar. Você deve localizar um registro a ser excluído, adicionar o objeto ao contexto e salvar com o SaveChanges. Neste exemplo a seguir, usei o método First com o Id igual a 13. Caso não exista, o método First retorna uma exception, por isto coloquei o tratamento de erro try/catch. Caso exista, basta chamar o método DeleteObject e passar o objeto contendo o produto selecionado.

private static void ExcluiProduto()
{
    try
    {
        using (var ctx = new MVA_EF4Entities())
        {
            var excluir = ctx.Produto.First(p => p.Id == 13);
            //ctx.Produto.DeleteObject(excluir);
            ctx.DeleteObject(excluir);
            ctx.SaveChanges();

            MostraDados();

            Console.ReadLine();
        }
    }
    catch (Exception)
    {
        Console.WriteLine("Ocorreu algum erro na exclusão.");
    }
}

Em casos de exclusão de dados relacionados é preciso tomar cuidado. Se você definir no EDM que todas as entidades relacionadas serão excluídas em cascata, ou seja, ao excluir o pai, automaticamente todos os filhos deste são excluídos. Outra opção é verificar se há algum filho deste pai, e caso não haja, aí sim você pode excluir o pai. Caso contrário você pode avisar o usuário que existem dados relacionados e não se pode excluir.

private static void ExcluiGrupo()
{
    try
    {
        using (var ctx = new MVA_EF4Entities())
        {
            var pesq = ctx.Produto.Where(p => p.IdGrupo == 10).Count();

            if (pesq == 0)
            {
                var excluir = ctx.Grupo.FirstOrDefault(g => g.Id == 10);
                ctx.DeleteObject(excluir);
                ctx.SaveChanges();
            }
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}

Resumindo, a manutenção de dados usando o EF 4 é muito claro, de fácil manutenção e o melhor de tudo é que as operações estão no mesmo contexto. E ainda, sem nenhuma linha de T-SQL. Indico que estude expressões Lambda e o LINQ (Language Integrated Query). No link http://www.renatohaddad.com/loja/AulasFree.aspx você encontra várias vídeo aulas gratuitas sobre o EF4.

JJ128160.80A5682C42DBDDD76F302471A33DCAF0(pt-br,MSDN.10).pnghttps://www.microsoftvirtualacademy.com/tracks/fundamentos-do-entity-framework-4


A Microsoft está realizando uma pesquisa online para saber sua opinião sobre o site do MSDN. Se você optar por participar, a pesquisa online lhe será apresentada quando você sair do site do MSDN.

Deseja participar?
Mostrar:
© 2014 Microsoft