Entity Framework 4: Lazy loading
Pessoal, vamos ver neste post como possibilitar o uso de lazy loading usando POCOs na versão CTP2 do Entity Framework 4. Vamos usar o projeto disponibilizado no post anterior, basta baixar o exemplo e criar uma nova solução chamada EF4LazyLoading e adicionar todos os projetos.
Após baixar o exemplo vamos mudar algumas coisas apenas para diferenciar do projeto anterior. vamos alterar o nome da classe no arquivo model.cs no projeto Model para EF4LazyLoadingModel, devemos trocar as referências também e não esquecer da string de conexão no arquivo DataContext.cs. Agora temos a solução inicial e podemos ver como funciona o lazyLoading no EF4.
1- Vamos criar uma classe chamada contact no nosso projeto classes
1: public class Contact
2: {
3: public Int32 ContactID { get; set; }
4: public String Name { get; set; }
5: public String Email { get; set; }
6: public String Phone { get; set; }
7: public String Address { get; set; }
8: public Person Person { get; set; }
9: public int PersonID { get; set; }
10: }
2- vamos adicionar uma lista de contatos na classe Person
1: public class Person
2: {
3: public int PersonID { get; set; }
4: public String Name { get; set; }
5: public int Age { get; set; }
6: public String Email { get; set; }
7: public List<Contact> Contacts { get; set; }
8: }
3- Agora vamos gerar um arquivo de configuração para a classe Contact
1: public class ContactConfiguration : EntityConfiguration<Contact>
2: {
3:
4: public ContactConfiguration()
5: {
6: Property(c => c.ContactID).IsIdentity();
7: Property(c => c.Name).IsRequired();
8:
9: //Indicando que o relacionamento possui uma regra(Constraint):O objeto Person possui uma coleção de Contacts
10: //com a seguinte regra: o id de Person deve ser o mesmo id de Person Dentro do objeto Contact
11: Relationship(c => c.Person).FromProperty(p => p.Contacts).HasConstraint((c, p) => c.PersonID == p.PersonID);
12: }
13: }
4- Precisamos alterar o arquivo de configuração de Person, vamos adicionar a seguinte linha
1: //Adicionando um relacionamento entre a coleção de Contacts do objeto Person
2: // e a propriedade Person do Objeto Contact
3: Relationship(p => p.Contacts).FromProperty(c => c.Person);
4:
5:
5- agora vamos adicionar a configuração de Contact no nosso DataContext
1: builder.Configurations.Add(new ContactConfiguration());
Agora nossa infra está pronta. vamos testar o lazyLoading.Para usar o lazyLoading como POCOs precisamos declarar a propriedade que será postergada como virtual e setar a opção LazyLoadingEnabled no Data Context.
6- Declarando a propriedade como virtual, vamos declarar a lista de contacts em Person como virtual
1: public virtual ICollection<Contact> Contacts { get; set; }
7-vamos setar o LazyLoadingEnabled no DataContext
1: public static EF4LazyLoadingModel FactoryDataContext()
2: {
3: String connection = @"Data Source=.\SQLEXPRESS;Initial Catalog=EF4LazyLoadingModel;Integrated Security=SSPI;";
4: var builder = new ContextBuilder<EF4LazyLoadingModel>();
5:
6: //Adicionamos todas as configurações
7: builder.Configurations.Add(new PersonConfiguration());
8: builder.Configurations.Add(new ContactConfiguration());
9:
10: var ctx = builder.Create(new SqlConnection(connection));
11: ctx.ContextOptions.LazyLoadingEnabled = true;
12: return builder.Create(new SqlConnection(connection));
13: }
Vamos rodar nosso exemplo e verificar o lazyLoading em ação
1: public static void Main()
2: {
3: //este método cria um database
4: DataContext.CreateDataBase();
5:
6: //Cadastradando uma pessoa
7: Person p = new Person();
8: p.Name = "Higor";
9: p.Age = 20;
10: p.Email = "higor.crr@gmail.com";
11:
12: var ctx = DataContext.FactoryDataContext();
13: ctx.People.AddObject(p);
14: ctx.SaveChanges();
15:
16: //Adicionando um contato
17: Contact c1 = new Contact();
18: c1.PersonID = p.PersonID;
19: c1.Name = "Higor";
20: c1.Phone = "1111-1111";
21: c1.Email = "higor@mail.com";
22: c1.Address = "RUA ABCD";
23:
24: ctx.Contacts.AddObject(c1);
25: ctx.SaveChanges();
26:
27: ctx = DataContext.FactoryDataContext();
28: var person = ctx.People.FirstOrDefault();
29:
30: //Aqui vamos ter problemas pois Contacts nao está carregado.
31: Console.WriteLine("Exibindo todos os contacts");
32: foreach (var item in person.Contacts)
33: {
34: Console.WriteLine("Name:" + item.Name);
35: }
36:
37: Console.ReadKey();
38:
39: }
Podemos usar uma técnica chamada explicitLoad, desta maneira vamos deixar claro que queremos carregar a lista de Contacts
1: ctx = DataContext.FactoryDataContext();
2: var person = ctx.People.FirstOrDefault();
3:
4: ctx.LoadProperty(person, x => x.Contacts);
5: Console.WriteLine("Exibindo todos os contacts");
6: foreach (var item in person.Contacts)
7: {
8: Console.WriteLine("Name:" + item.Name);
9: }
Então, vocês acharam dificil? isso é o básico.. nos proximos posts vou explicar como funciona o lazyLoading e o motivo pelo qual usamos virtual na propriedade. pra quem quiser se adiantar no assunto vou deixar no final do post uns links.
Links:
http://blogs.msdn.com/adonet/archive/2009/12/22/poco-proxies-part-1.aspx