Entity Framework
Entity Framework: The property ‘xx’ on type ‘xx’ cannot be set because the collection is already set to an EntityCollection
0Olá pessoal, depois de muito tempo sem falar sobre EntityFramework vou falar sobre o bug do titulo.
Problema
Vamos usar o Entity Framework 4.3.1 com o seguinte modelo
public class Blog
{
public int BlogID { get; set; }
public string Titulo { get; set; }
public string Url { get; set; }
public virtual ICollection Posts { get; set; }
}
public class Post
{
public virtual int BlogID { get; set; }
public virtual int PostID { get; set; }
public virtual string Titulo { get; set; }
public virtual string Conteudo { get; set; }
public virtual ICollection Comentarios { get; set; }
public Post()
{
Comentarios = new HashSet();
}
}
public class Comentario
{
public int PostID { get; set; }
public int ComentarioID { get; set; }
public string NomeAutor { get; set; }
public string Texto { get; set; }
}
O erro acontece quando temos o seguinte cenário: Temos uma entidade mapeada para usar change tracking proxy e existe a necessidade de utilizar a coleção contida nessa entidade durante o processo de criaçao de um novo post.
1: var contexto = new ContextoAcessoDados();
2: var blog = contexto.Blogs.FirstOrDefault();
3:
4: var novoPost = new Post { Titulo = "post novo já comentado", Conteudo = "conteudo do post novo" };
5: novoPost.Comentarios.Add(new Comentario { NomeAutor = "Joao", Texto = "como adicionar em dados em coleções usando o ef" });
6: blog.Posts.Add(novoPost);
7:
8: contexto.SaveChanges();
Ao executar I método saveChanges temos a seguinte mensagen:
The property ‘Comentarios’ on type ‘Post_51FA4C11FB3F248409B06D408BFBDEC68A302B257733726D76E931873D4398BC’ cannot be set because the collection is already set to an EntityCollection.
Solução
Acredite se quiser, mas a solução é desabilitar o change tracking proxy, isso mesmo você deve remover o modificador virtual das propriedades básicas e deixar apenas a coleção de comentários como virtual,a entidade alterada fica assim:
1: public class Post
2: {
3: public int BlogID { get; set; }
4: public int PostID { get; set; }
5: public string Titulo { get; set; }
6: public string Conteudo { get; set; }
7: public virtual ICollection Comentarios { get; set; }
8:
9: public Post()
10: {
11: Comentarios = new HashSet();
12: }
13: }
Pronto! agora o código funciona sem problemas. A solução foi tirada de uma thread no msdn
Espero que ajude pessoal, segue o código de exemplo para downloadOlá pessoal, depois de muito tempo sem falar sobre EntityFramework vou falar sobre o bug do titulo.
Problema
Vamos usar o Entity Framework 4.3.1 com o seguinte modelo
public class Blog
{
public int BlogID { get; set; }
public string Titulo { get; set; }
public string Url { get; set; }
public virtual ICollection Posts { get; set; }
}
public class Post
{
public virtual int BlogID { get; set; }
public virtual int PostID { get; set; }
public virtual string Titulo { get; set; }
public virtual string Conteudo { get; set; }
public virtual ICollection Comentarios { get; set; }
public Post()
{
Comentarios = new HashSet();
}
}
public class Comentario
{
public int PostID { get; set; }
public int ComentarioID { get; set; }
public string NomeAutor { get; set; }
public string Texto { get; set; }
}
O erro acontece quando temos o seguinte cenário: Temos uma entidade mapeada para usar change tracking proxy e existe a necessidade de utilizar a coleção contida nessa entidade durante o processo de criaçao de um novo post.
1: var contexto = new ContextoAcessoDados();
2: var blog = contexto.Blogs.FirstOrDefault();
3:
4: var novoPost = new Post { Titulo = "post novo já comentado", Conteudo = "conteudo do post novo" };
5: novoPost.Comentarios.Add(new Comentario { NomeAutor = "Joao", Texto = "como adicionar em dados em coleções usando o ef" });
6: blog.Posts.Add(novoPost);
7:
8: contexto.SaveChanges();
Ao executar I método saveChanges temos a seguinte mensagen:
The property ‘Comentarios’ on type ‘Post_51FA4C11FB3F248409B06D408BFBDEC68A302B257733726D76E931873D4398BC’ cannot be set because the collection is already set to an EntityCollection.
Solução
Acredite se quiser, mas a solução é desabilitar o change tracing proxy, isso mesmo você deve remover o modificador virtual das propriedades básicas e deixar apenas a coleção de comentários como virtual,a entidade alterada fica assim:
1: public class Post
2: {
3: public int BlogID { get; set; }
4: public int PostID { get; set; }
5: public string Titulo { get; set; }
6: public string Conteudo { get; set; }
7: public virtual ICollection Comentarios { get; set; }
8:
9: public Post()
10: {
11: Comentarios = new HashSet();
12: }
13: }
Pronto! agora o código funciona sem problemas. A solução foi tirada de uma thread no msdn
Espero que ajude pessoal, segue o código de exemplo para download
EF 4.1: Mapear uma tabela para várias entidades
1Olá pessoal, desta vez vamos ver como mapear uma tabela em várias entidades, uso como base e inspiração esse post aqui. A técnica é bem valiosa nos cenários de uso do EF em sistemas legados, hoje eu estou trabalhando a maior parte na migração de um sistema asp para .NET 4, o grande problema é que o banco de dados é legado e realizado de uma maneira que não ajuda o desenvolvimento baseado em OO( não existe coesão e separação de conceitos) então essa funcionalidade ajuda a diminuir o gap entre o domínio e banco de dados.
1- Modelo de dados
2-Entidade de mapeamento
Vamos separar o endereço em uma entidade separada para tentarmos aumentar a coesão e caminhar em busca de um modelo mais simples e delineado.Então ficamos com as duas entidades abaixo:
3- Configuração do mapeamento
Você pode reparar que foi necessário definir uma coluna e configurar a chave primária na entidade endereço e ainda foi configurado um relacionamento com as duas pontas obrigatórias.
4-Exemplo
É isso pessoal, em breve vou falar mais sobre algumas configurações de relacionamentos com foco em modelo rico e OO.
EF 4.1 Cascade
1Olá pessoal, dessa vez o assunto será a configuração de deleção em cascata do EntityFramework 4.1. A motivação para criar o post foi a dúvida de alguns amigos no twitter, enquanto o time do EF não libera novidades pretendo escrever posts baseados nas dúvidas da galera, então vamos ao cascade.
1-Entidades
2-Contexto
A configuração da primeira entidade define um relacionamento um para n(hasmany() e withRequired()) e habilita a deleção em cascata
3-Exemplos
Dica
A configuração da deleção em cascata usando WillCascadeOnDelete() é dependente da configuração do relacionamento, é possível configurar o relacionamento de diferentes maneiras, caso o cascade não funciona a dica é rever a configuração de chaves estrangeiras e relacionamentos.
EF 4.1 Implementação de repositório genérico
4Olá pessoal, usando como base a implementação de repositório genérico do LiteFx eu fiz algumas alterações e criei um repositório genérico usando o EF4.1 como base. segue a implementação e exemplo
1-Implementação do repositório
2-Exemplo de uso
EF4.1 Relacionamentos com e sem chave estrangeira
0Olá pessoal, na minha série de posts sobre Entity Framework já postei diversos códigos de relacionamentos com ou sem chave estrangeira. O intuito desse post é colocar as duas maneiras lado a lado. Eu geralmente não crio as chaves estrangeiras quando estou criando o modelo e banco de dados, já em sistemas legados é comum manter o modelo, logo as chaves estrangeiras são mapeadas. Então, vamos ao código
1- Entidades
Como podem ver na classe Livro temos uma referência para Autor com uma chave estrangeira AutorID e uma referência para Editora sem chave.
2-Configurações de mapeamento
O Arquivo de configuração mais importante é o LivroConfiguracao.cs, a primeira configuração de relacionamento é entre Livro e Editora e não possui chave de mapeamento. Já a segunda configuração é entre Autor e Livro e nesse caso o método HasForeignKey é usado definindo AutorID como uma chave estrangeira Pronto!Isso é suficiente para a criação dos relacionamentos, agora vamos ver o código do Contexto e o exemplo.
3-Contexto
4-Exemplo
É isso pessoal, recebi perguntas de algumas dúvidas sobre as diferenças entre relacionamentos com e sem chave e resolvi criar um exemplo. Espero que ajude e até a próxima
Entity Framework 4.1
2por que mais uma versão?
Quem já usou Entity Framework 1 ou “4” com EDMX e precisou de customização sabe como é difícil. A versão 4.1 traz uma série de novidades que possibilitam um desenvolvimento mais simples, flexível e considerações sobre boas maneiras de desenvolver. O time do Entity Framework mantém um blog para ouvir a comunidade e planejar futuras implementações
O que temos nessa versão
Olá pessoal, essa semana o time de ado.net anunciou o release do entity framework 4.1 aka CodeFirst/CodeOnly. Como você já deve ter ouvido falar esse framework disponibiliza uma nova maneira de usar a sólida base do ADO.NET com melhores padrões de desenvolvimento como SoC e DRY, se você ainda não conhece muito sobre esse framework pode aprender um pouco sobre na série de posts que fiz sobre o assunto.
Após esse anuncio ficou bem claro que não vamos atualizar e vamos continuar com o ctp5, não podemos abrir mãos de algumas features cortadas. Vamos seguir usando o ef esperando que tenhamos em breve mais um ctp com features como migrations e queries compiladas.
O que deveríamos ter nessa versão
- Execução de stored procedures
- Suporte a queries compiladas
É estável
Eu venho usando o framework desde o CTP1 e não tive problemas com bugs mágicos. Já coloquei mais de cinco sistemas em produção e tudo corre bem. Hoje estou trabalhando em um projeto grande e usamos EF em alguns pontos sem problemas, então se o medo for estabilidade vai fundo.
Quando usar ?
- Quando você já possui alguma experiência com entity framework 4
- Precisa ter controle sobre seus objetos de domínio ou mapeamento
- Não precisa de algumas das features como execução de stored procedures
Mais informações
http://blogs.msdn.com/b/adonet/archive/2011/03/15/ef-4-1-release-candidate-available.aspx
http://blogs.msdn.com/b/adonet/archive/2011/03/02/ef-4-1-is-coming-dbcontext-api-amp-code-first-rtw.aspx
http://blogs.msdn.com/b/adonet/archive/2011/03/15/ef-4-1-code-first-walkthrough.aspx
http://blogs.msdn.com/b/efdesign/
Conclusão
Espero que o post possa ser útil para decidir se usar ou não Entity Framework 4.1
Entity Framework 4 CTP 5 Parte 7: Queries SQL
2O suporte a queries SQL do EF4 CTP5 já funciona tanto para comandos sql quanto para stored procedures. Neste post vamos abordar a execução de comandos considerando alguns pontos como Banco de dados legado e stored procedures com parâmetros de saida.
Comandos SQL em tabela com colunas diferentes do objeto de domínio
Quando a tabela do banco de dados possui nomes de colunas não equivalentes a propriedades do objeto de domínio é necessário usar alias durante a execução da querie. Segue um exemplo.
Classe de domínio:
Comando SQL:
Execução de Stored Procedures com parâmetros de saida
A execução de procedures com parâmetros pode ser configurada na criação do parâmetro, usando entre eles o atributo Direction, segue um exemplo.
Pessoal, pela facilidade co código não coloquei o projeto no GitHub. Quem tiver problema ou dúvida só entrar em contato.
Entity Framework 4 CTP5 parte 6: Testes unitários
1Olá pessoal, uma grande novidade na versão 4 do Entity Framework(EF) foi a criação de interfaces para facilitar o desenvolvimento de testes unitários para solução. Aliando a testabilidade do EF com o poder de ferramentas como o AutoPoco e Unity podemos escrever testes unitários para repositórios baseados em LINQ facilmente. Segue o exemplo:
Representação do domínio
Entidades:
Interfaces de repositório:
Interface do contexto de acesso a dados(DbContext):
O tipo da coleção é IDbSet
Na criação do contexto falso uma implementação "Fake" do IDbSet será usada para armazenar dados em memória Implementação do contexto de acesso a dados baseado no EF:
Ok, temos a base para a criação da implementação do repositório.O repositório vai criar a implementação do contexto de acesso a dados usando injeção de dependência, assim será possível implementar uma versão "fake" do contexto de acesso a dados e continuar com as queries LINQ rodando sobre o contexto injetado.
O papel do construtor é usar a API do Unity para resolver uma dependência do tipo IContextoAcessoDados.Se quiser saber mais sobre o Unity basta olhar a documentação aqui.
Projeto de testes
A primeira coisa a fazer será criar uma implementação "Fake" da interface IDbSet que armazene os dados em memória, segue o código:
Olhando a implementação dos métodos é fácil entender que a classe armazena os dados na lista _entities e realiza todas as operações sobre os dados em memória.
Agora é necessário criar a implementação do ContextoAcessoDados que utiliza o FakeDbSet
A implementação de ContextoAcessoDados do projeto de testes está pronta, agora é necessário configurar o container de do Unity.
A configuração será feita no App.config:
Todas as configurações estão prontas, agora só resta escrever os testes.
Testes unitários
Podemos escrever os seguintes testes:
Nossa coleção de dados para testes ainda está vazia, fazendo com que os teste falhem.
Para criar dados de testes vamos usar o AutoPoco
Configuração do AutoPoco
No código do AutoPoco criando dados com as seguintes regras:
- Serão criadas 5 entidades
- As duas primeiras entidades possuem CPF de numero::111222333-33,
- As três ultimas entidades possuem CPF de número:456222333-33
- Todas as entidades possuem nome igual a “Higor”
Após a criação os dados são inseridos na coleção em memória através do método adicionar do repositório.
Conclusão e referências
Pronto! todo o ambiente está pronto. Certamente existem outras possibilidades de testar queries LINQ, estou usando uma arquitetura de testes nos meus projetos baseada no exemplo do post e tudo está funcionando bem.
Entity Framework 4 CTP5 parte 5: Mapeamento de tipos do SQLServer 2008 e Eager Loading
0
Mapeamento de tipos do Banco de dados
Utilizando o EF durante um projeto onde o banco de dados é legado(está longe de ser normalizado ou com bons nomes) as vezes pe necessário mapear tipos do banco de dados para CLR. Existe essa tabela que ajuda muito esse trabalho. Ou ainda pode ser necessário usar o método HasColumnType(), segue o exemplo:
Definição da classe:
Classe de mapeamento:
Eager Loading
Código fonte:
https://github.com/HigorCesar/ConfiguracoesAdicionaisEF4CTP5
Pessoal o proximo post será sobre como escrever testes unitários para as queries LINQ usando Coleção em memória e AutoPoco
Entity Framework 4 CTP 5 parte 4: Relacionamentos
0Olá pessoal, estava planejando um post sobre configurações não-triviais do EF4CTP5 mas pesquisando durante a semana sobre mapeamento de relacionamentos no EF4CTP5 vi que não achei uma coisa realmente sucinta e com exemplos, então vamos abordar como mapear relacionamentos com a interface fluente do EF.
Interface fluente
Uma maneira de implementar uma API orientada a objetos de uma maneira que forneça um código de leitura mais facil.
Pessoal, nao vou considerar um modelo orientado a dominio.O foco é apenas a definição dos relacionamentos, em casos reais o modelo aqui apresentado não deve fazer muito sentido.
Relacionamento 1-1
Uma pessoa possui uma conta de usuário
Classes utilizadas no mapeamento:
Classes de configuração:
No arquivo de configuração UsuarioConfiguracao.cs definimos o seguinte relacionamento:
Um usuário possui obrigatoriamente uma pessoa associada
e uma pessoa possui um usuário associado sendo usuário dependente de pessoa
Relacionamento 1-N
Uma pessoa gerencia vários projetos
Classes utilizadas no mapeamento:
Classes de configuração:
No arquivo projetoconfiguracao.cs definimos o seguinte relacionamento:
Um projeto possui obrigatoriamente uma pessoa associada
e uma pessoa pode possuir varios projetos associados.
Na configuração de projeto podemos reparar que a chave é composta, essa é uma das maneiras de manter a integridade utilizadas pelo EntityFramework, existem outras maneiras de configurar um relacionamento 1 para N, por exemplo usando uma tabela de junção.
Relacionamento N-N
Um projeto utiliza diversas tecnologias que são utilizadas em diversos projetos
Classes utilizadas no mapeamento:
Classes de configuração:
No arquivo tecnologiaconfiguracao.cs definimos o seguinte relacionamento:
Uma tecnologia está associada a muitos projetos
Um projeto por sua vez está relacionado a muitas tecnologias
Relacionamentos N para N precisam de uma tabela auxiliar, definimos essa estrutura na seguinte parte:
Estamos definindo o mapeamento m e suas chaves(LeftKey e RightKey) e os respectivos nomes de colunas
É isso pessoal. o foco foi citar o mapeamento minimo de relacionamentos necessário para utilizar o EF4CTP5
Código dos exemplos:
https://github.com/HigorCesar/MapeandoRelacionamentosEFCTP5
Mais sobre mapeamento fluente:
http://blogs.msdn.com/b/adonet/archive/2010/12/10/code-first-mapping-changes-in-ctp5.aspx