none
NHibernate - LazyLoad e EagerLoad RRS feed

  • Pergunta

  • Olá Pessoal

    Sou novato em NHibernate e estou com uma duvida de como configurar o LazyLoad e o EagerLoad

    Tenho 2 classes bem simples que é Cliente e Telefone, um cliente tem vários telefone, é só uam situação didática para estudo.

    A duvida é o seguinte na TAG <hibernate-mapping> eu coloquei o atributo default-lazy="false", mas mesmo assim os telefone são carregados quando o cliente é carregado.Eu gostaria de desabilitar o lazy load

    Classes

    Cliente

    using System;
    using System.Collections;
    
    namespace NHibernateLoadData.Classes
    {
        public class Cliente
        {
            private int _id;
            private string _nome;
            private IList _telefones;
    
            public int Id
            {
                get { return _id; }
                set { _id = value; }
            }
    
            public string Nome
            {
                get { return _nome; }
                set { _nome = value; }
            }
    
            public IList Telefones
            {
                get { return _telefones; }
                set { _telefones = value; }
            }
        }
    }

    Telefone

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace NHibernateLoadData.Classes
    {
        public class Telefone
        {
            private int _id;
            private string telefoneRes;
            private string telefoneCom;
            private Cliente _cliente;
    
            public int Id
            {
                get { return _id; }
                set { _id = value; }
            }
    
            public string TelefoneRes
            {
                get { return telefoneRes; }
                set { telefoneRes = value; }
            }
    
            public string TelefoneCom
            {
                get { return telefoneCom; }
                set { telefoneCom = value; }
            }
    
            public Cliente Cliente
            {
                get { return _cliente; }
                set { _cliente = value; }
            }
        }
    }

    Mapeamentos

    Cliente

    <?xml version="1.0" encoding="utf-8" ?>
    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NHibernateLoadData" namespace=" NHibernateLoadData.Classes" default-lazy="false">
      <class name="Cliente"  table ="Cliente">
        
        <id name="Id" column="IdCliente" type="Int32" >
          <generator class="native" />
        </id>
        <property name="Nome" column ="nome" type="String" length="50" />
    
        <bag name="Telefones">
          <key column="Cliente_Id" />
          <one-to-many class="Telefone" />
        </bag>
    
      
    </class>
    </hibernate-mapping>

    Telefone

    <?xml version="1.0" encoding="utf-8" ?>
    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NHibernateLoadData" namespace=" NHibernateLoadData.Classes" default-lazy="false">
      <class name="Telefone" table ="Telefone">
    
        <id name="Id" column="IdTelefone" type="Int32" >
          <generator class="native" />
        </id>
        <property name="TelefoneRes" column ="TelefoneRes" type="String" length="50" />
        <property name="TelefoneCom" column ="TelefoneCom" type="String" length="50" />
    
        <many-to-one name="Cliente" column="Cliente_Id" class="Cliente"/>
        
      </class>
    </hibernate-mapping>

    Método de listagem dos clientes

    using (ISession session = NHibernateSession.OpenSession())
                {
                    IList<Cliente> clientes = session.CreateCriteria(typeof(Cliente)).List<Cliente>();
                    foreach (var cliente in clientes)
                    {
                        Console.WriteLine("Cliente: {0}", cliente.Nome);
    
                        foreach (Telefone telefone in cliente.Telefones)
                        {
                            Console.WriteLine(" Telefone: {0} - {1}",
                                telefone.TelefoneRes, telefone.TelefoneCom);
                            
                        }
                    }
                    Console.ReadLine();
                }


    terça-feira, 3 de julho de 2012 12:30

Respostas

Todas as Respostas

  • Amigo, se você quer que a carga das entidades seja sob demanda então o lazy tem de ser igual a true

    Olavo Oliveira Neto
    http://olavooneto.wordpress.com
    Twitter @Olavooneto
    Facebook Olavo Neto
    Linkedin Olavo Neto
    Se for útil marque como resposta e faça um Developer feliz :)

    terça-feira, 3 de julho de 2012 15:47
  • Não não, eu gostaria de desabilitar o Lazy Load e usar o Eager Load, mas para isso eu coloquei default-lazy="false", mas não funcionou

    No entity framework eu fiz desse jeito:

    ctx.ContextOptions.LazyLoadingEnabled = false;
    
     var clientes = ctx.Cliente.Include("Telefone");

    Mas no NHibernate eu não sei fazer

    terça-feira, 3 de julho de 2012 17:23
  • <class name="Cliente" table ="Cliente" lazy="false">

    Mas você poderia deixar como lazy e ter o controle dinâmico de desligar os lazys usando fetch em criteria ou queryover.
    quarta-feira, 4 de julho de 2012 02:11
  • rs.developer

    Obrigado pela resposta eu sou estou iniciando com o nhibernate eu não sei muito coisa, você teria um exemplo de criteria e queryover

    quarta-feira, 4 de julho de 2012 14:21
  • Exemplo em queryover:

                var resultado = Session.QueryOver<Cliente>()
                        .Where(c => c.AlgumaPropriedadeSeTiverPesquisando == "teste")
                        .Fetch(f => f.Xxxxxxx).Eager
                        //.TransformUsing(Transformers.DistinctRootEntity)
                        .List<Cliente>();

    Xxxxxxx = Se você tiver alguma propriedade com lazy você poe ai pra desligar o lazy na query, e por mais .Fetchs se quiser.
    (No mapeamento você pode setar o lazy por propriedade e não só a nível de classe.)

    TransformUsing(Transformers.DistinctRootEntity) -> Usar quando uma das propriedades com fetch for lista para não acontecer de duplicar cliente por cada item da lista.

    QueryOver é mais moderno do que Criteria, mas se tiver alguma situação que não funcione ainda com queryover é só pesquisar pois segue o mesmo conceito, internamente QueryOver usa criteria.

    Não sei se já conhece mas existem outros tipos de mapeamentos além do XML. O modo mais novo é mapping by code.

    • Editado rs.developer quinta-feira, 5 de julho de 2012 03:35
    quinta-feira, 5 de julho de 2012 00:33