Hola a todos.

Tengo problemas para poder serializar a XML una lista de un modelo 
especifico del dominio. Ya intente de todo: Propiedades surrogadas, 
poniendo el lazyload en false a la entidad y sus bags. Tambien intente 
"desproxificar" la entidad.
El problema, en cuestion, es mas que nada la serializacion XML es que me 
lanza una excepcion ProxyAcessException. Al parecer NH esta intentando 
acceder a propiedades no mapeadas en el mapping correspondiente. Busque la 
manera de que, en el mapping, ignore la propiedad pero no existe tal cosa 
en NH.

Les dejo parte del codigo aca y si hay que revisar mas a fondo el 
repositorio: escuela-simple <https://github.com/drielnox/escuela-simple>

Entidad:

namespace EscuelaSimple.Modelos
{
    [Serializable()]
    public class Personal : IEntidad<uint>
    {
        [XmlAttribute]
        public virtual uint Identificador { get; set; }
        public virtual string Nombre { get; set; }
        public virtual string Apellido { get; set; }
        public virtual uint DNI { get; set; }
        public virtual DateTime FechaNacimiento { get; set; }
        public virtual string Domicilio { get; set; }
        public virtual string Localidad { get; set; }
        [XmlIgnore]
        public virtual ICollection<Telefono> Telefonos { get; protected set; }
        [XmlElementAttribute(IsNullable = true)]
        public virtual DateTime? IngresoDocencia { get; set; }
        [XmlElementAttribute(IsNullable = true)]
        public virtual DateTime? IngresoEstablecimiento { get; set; }
        public virtual string Titulo { get; set; }
        public virtual string Cargo { get; set; }
        public virtual string SituacionRevista { get; set; }
        public virtual string Observacion { get; set; }
        [XmlIgnore]
        public virtual ICollection<Inasistencia> Inasistencias { get; protected 
set; }
 
        public Personal()
        {
            this.Telefonos = new List<Telefono>();
            this.Inasistencias = new List<Inasistencia>();
        }
 
        public void AgregarTelefono(Telefono telefono)
        {
            if (!this.Telefonos.Contains(telefono))
            {
                this.Telefonos.Add(telefono);
            }
        }
 
        public void QuitarTelefono(Telefono telefono)
        {
            if (this.Telefonos.Contains(telefono))
            {
                this.Telefonos.Remove(telefono);
            }
        }
 
        public void AgregarInasistencia(Inasistencia inasistencia)
        {
            if (!this.Inasistencias.Contains(inasistencia))
            {
                this.Inasistencias.Add(inasistencia);
            }
        }
 
        public void QuitarInasistencia(Inasistencia inasistencia)
        {
            if (this.Inasistencias.Contains(inasistencia))
            {
                this.Inasistencias.Remove(inasistencia);
            }
        }
 
        #region Surrogacion para XMLSerializer 
 
        /*
         Walkaround para poder serializar a XML el proxy.
         */
 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        [XmlArray(ElementName = "Telefonos"), XmlArrayItem("Telefono", 
typeof(Telefono))]
        public virtual List<Telefono> ListaDeTelefonosSurrogado
        {
            get
            {
                List<Telefono> proxy = this.Telefonos as List<Telefono>;
                if (proxy == null && this.Telefonos != null)
                {
                    proxy = (List<Telefono>)this.Telefonos;
                }
 
                return proxy;
            }
            set
            {
                this.Telefonos = value;
            }
        }
 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        [XmlArray(ElementName = "Inasistencias"), XmlArrayItem("Inasistencia", 
typeof(Inasistencia))]
        public virtual List<Inasistencia> ListaDeInasistenciasSurrogada
        {
            get
            {
                List<Inasistencia> proxy = this.Inasistencias as 
List<Inasistencia>;
                if (proxy == null && this.Inasistencias != null)
                {
                    proxy = (List<Inasistencia>)this.Inasistencias;
                }
 
                return proxy;
            }
            set
            {
                this.Inasistencias = value;
            }
        }
 
        #endregion
 
        #region Sobrecarga a Object
 
        public override bool Equals(object obj)
        {
            if (obj == null)
            {
                return false;
            }
 
            Personal personal = obj as Personal;
            if (personal == null)
            {
                return false;
            }
 
            return this.Identificador.Equals(personal.Identificador) &&
                this.Nombre.Equals(personal.Nombre) &&
                this.Apellido.Equals(personal.Apellido) &&
                this.DNI.Equals(personal.DNI) &&
                this.FechaNacimiento.Equals(personal.FechaNacimiento);
        }
 
        public override int GetHashCode()
        {
            string hashCode = this.Identificador + "|" + this.Nombre + "|" + 
this.Apellido + "|" +
                this.DNI + "|" + this.FechaNacimiento + "|" + this.Domicilio + 
"|" +
                this.Localidad + "|" + this.Telefonos + "|" + 
this.IngresoDocencia + "|" +
                this.IngresoEstablecimiento + "|" + this.Titulo + "|" + 
this.Cargo + "|" +
                this.SituacionRevista + "|" + this.Observacion + "|" + 
this.Inasistencias;
            return hashCode.GetHashCode();
        }
 
        #endregion
    }
}


Mapeo:

namespace EscuelaSimple.Datos.Mapeo.NHibernate
{
    public class PersonalMap : ClassMapping<Personal>
    {
        public PersonalMap()
        {
            Lazy(false);
 
            Table("Personal");
 
            Id<uint>(x => x.Identificador, m =>
            {
                m.Access(Accessor.Property);
                m.Column("IdPersonal");
                m.Generator(Generators.Identity);
            });
 
            Property<string>(x => x.Nombre, m =>
            {
                m.Access(Accessor.Property);
                m.Column("Nombre");
                m.NotNullable(true);
            });
            Property<string>(x => x.Apellido, m =>
            {
                m.Access(Accessor.Property);
                m.Column("Apellido");
                m.NotNullable(true);
            });
            Property<uint>(x => x.DNI, m =>
            {
                m.Access(Accessor.Property);
                m.Column("DNI");
                m.UniqueKey("UK_Personal_DNI");
                m.NotNullable(true);
            });
            Property<DateTime>(x => x.FechaNacimiento, m =>
            {
                m.Access(Accessor.Property);
                m.Column("FechaNacimiento");
                m.NotNullable(true);
                m.Type<DateType>();
            });
            Property<string>(x => x.Domicilio, m =>
            {
                m.Access(Accessor.Property);
                m.Column("Domicilio");
                m.NotNullable(false);
            });
            Property<string>(x => x.Localidad, m =>
            {
                m.Access(Accessor.Property);
                m.Column("Localidad");
                m.NotNullable(false);
            });
            Property<DateTime?>(x => x.IngresoDocencia, m =>
            {
                m.Access(Accessor.Property);
                m.Column("IngresoDocencia");
                m.NotNullable(false);
                m.Type<DateType>();
            });
            Property<DateTime?>(x => x.IngresoEstablecimiento, m =>
            {
                m.Access(Accessor.Property);
                m.Column("IngresoEstablecimiento");
                m.NotNullable(false);
                m.Type<DateType>();
            });
            Property<string>(x => x.Titulo, m =>
            {
                m.Access(Accessor.Property);
                m.Column("Titulo");
                m.NotNullable(false);
            });
            Property<string>(x => x.Cargo, m =>
            {
                m.Access(Accessor.Property);
                m.Column("Cargo");
                m.NotNullable(false);
            });
            Property<string>(x => x.SituacionRevista, m =>
            {
                m.Access(Accessor.Property);
                m.Column("SituacionRevista");
                m.NotNullable(false);
            });
            Property<string>(x => x.Observacion, m =>
            {
                m.Access(Accessor.Property);
                m.Column("Observacion");
                m.NotNullable(false);
            });
 
            Set<Telefono>(x => x.Telefonos,
                cm =>
                {
                    cm.Access(Accessor.Property);
                    cm.Table("Telefono");
                    cm.Key(k =>
                    {
                        k.Column(c =>
                        {
                            c.Name("IdPersonal");
                            c.NotNullable(true);
                            c.UniqueKey("UK_Telefono_2");
                        });
                        k.ForeignKey("FK_Telefono_Personal_1");
                        k.NotNullable(true);
                    });
                    cm.Cascade(Cascade.All);
                    cm.Lazy(CollectionLazy.NoLazy);
                },
                m =>
                {
                    m.OneToMany(x =>
                    {
                        x.Class(typeof(Telefono));
                        x.NotFound(NotFoundMode.Exception);
                    });
                });
            Set<Inasistencia>(x => x.Inasistencias,
                cm =>
                {
                    cm.Access(Accessor.Property);
                    cm.Table("Inasistencia");
                    cm.Key(k =>
                    {
                        k.Column(c =>
                        {
                            c.Name("IdPersonal");
                            c.NotNullable(true);
                        });
                        k.ForeignKey("FK_Inasistencia_Personal_1");
                        k.NotNullable(true);
                    });
                    cm.Cascade(Cascade.All);
                    cm.Lazy(CollectionLazy.NoLazy);
                },
                m =>
                {
                    m.OneToMany(x =>
                    {
                        x.Class(typeof(Inasistencia));
                        x.NotFound(NotFoundMode.Exception);
                    });
                });
        }
    }
}


Repositorio Generico para NH:

namespace EscuelaSimple.Datos.Repositorio
{
    public abstract class NHibernateRepositorio<TEntidad, TClavePrimaria> : 
IRepositorio<TEntidad, TClavePrimaria>
        where TEntidad : class, IEntidad<TClavePrimaria>
        where TClavePrimaria : struct
    {
        public ISession Sesion { get; set; }
 
        public NHibernateRepositorio(ISession sesion)
        {
            this.Sesion = sesion;
        }
 
        public TEntidad ObtenerPorIdentificador(TClavePrimaria id)
        {
            return this.Sesion.Get<TEntidad>(id);
        }
 
        public IEnumerable<TEntidad> ObtenerTodo()
        {
            IQueryOver<TEntidad> result = this.Sesion.QueryOver<TEntidad>();
            return result.List(); // <<< Aca tira ProxyAccessException!!!
        }
 
        public void Crear(TEntidad entity)
        {
            this.Sesion.Save(entity);
        }
 
        public void Actualizar(TEntidad entity)
        {
            this.Sesion.Update(entity);
        }
 
        public void Borrar(TEntidad entity)
        {
            this.Sesion.Delete(entity);
        }
 
        public TEntidad ObtenerPor(Predicate<TEntidad> predicate)
        {
            List<TEntidad> result = this.FiltrarPor(predicate) as 
List<TEntidad>;
            return result.Count > 0 ? result[0] : null;
        }
 
        public IEnumerable<TEntidad> FiltrarPor(Predicate<TEntidad> predicate)
        {
            List<TEntidad> result = this.ObtenerTodo() as List<TEntidad>;
            return result.FindAll(predicate);
        }
    }
}


Negocio donde obtengo la lista de la entidad requerida:

namespace EscuelaSimple.Negocio
{
    public class PersonalNegocio
    {
        private IUnidadDeTrabajo _unitOfWork;
        private IPersonalRepositorio _repoPersonal;
 
        public PersonalNegocio()
        {
            this._unitOfWork = new 
NHibernateUnidadDeTrabajo(NHibernateWrapper.CurrentSession);
            this._repoPersonal = new 
PersonalRepositorio(NHibernateWrapper.CurrentSession);
        }
 
        public List<Personal> ObtenerTodoPersonal()
        {
            try
            {
                IEnumerable<Personal> listaPersonal = 
this._repoPersonal.ObtenerTodo();
                //this._unitOfWork.SaveChanges();
                return listaPersonal as List<Personal>;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
 
        public List<Personal> ObtenerTodoPersonalSerializable()
        {
            try
            {
                IPersistenceContext unproxier = 
NHibernateWrapper.CurrentSession.GetSessionImplementation().PersistenceContext;
                IEnumerable<Personal> listaPersonal = 
this._repoPersonal.ObtenerTodo();
                List<Personal> listaARetornar = new List<Personal>();
                
                foreach (Personal item in listaPersonal)
                {
                    Personal personalSerializable = 
(Personal)unproxier.Unproxy(item);
                    listaARetornar.Add(personalSerializable);
                }
 
                return listaARetornar;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
 
        public List<Personal> ObtenerPersonal(Personal personal)
        {
            try
            {
                IEnumerable<Personal> listaPersonal = 
this._repoPersonal.FiltrarPor(x =>
                {
                    return 
x.Apellido.ToLower().StartsWith(personal.Apellido.ToLower()) ||
                        
x.DNI.ToString().ToLower().StartsWith(personal.DNI.ToString().ToLower());
                });
                //this._unitOfWork.SaveChanges();
                return listaPersonal as List<Personal>;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
 
        public void BorrarPersonal(Personal personalSeleccionado)
        {
            try
            {
                this._repoPersonal.Borrar(personalSeleccionado);
                //this._unitOfWork.SaveChanges();
            }
            catch (Exception ex)
            {
                throw ex;
            }            
        }
 
        public void GuardarPersonal(Personal personalAGuardar)
        {
            try
            {
                this._repoPersonal.Crear(personalAGuardar);
                //this._unitOfWork.SaveChanges();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
 
        public void ActualizarPersonal(Personal personalAGuardar)
        {
            try
            {
                this._repoPersonal.Actualizar(personalAGuardar);
                //this._unitOfWork.SaveChanges();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }
}


Lugar donde se solicita la serializacion XML:

private void tsmiExportar_Click(object sender, EventArgs e)
{
    SaveFileDialog saveFileDialog = new SaveFileDialog();
    saveFileDialog.InitialDirectory = 
Environment.GetFolderPath(Environment.SpecialFolder.Personal);
    saveFileDialog.Filter = "Archivo XML (*.xml)|*.xml|Todos los archivos 
(*.*)|*.*";
    if (saveFileDialog.ShowDialog(this) == DialogResult.OK)
    {
        string FileName = saveFileDialog.FileName;
 
        List<Modelos.Personal> listaPersonal = 
this._personalNegocio.Value.ObtenerTodoPersonalSerializable();
        XmlSerializer serializer = new 
XmlSerializer(typeof(List<Modelos.Personal>));
        using (StreamWriter myWriter = new StreamWriter(FileName))
        {
            serializer.Serialize(myWriter, listaPersonal);
        }
    }
}


Saludos!

-- 
-- 
Para escribir al Grupo, hágalo a esta dirección: 
[email protected]
Para más, visite: http://groups.google.com/group/NHibernate-Hispano
--- 
Has recibido este mensaje porque estás suscrito al grupo "NHibernate-Hispano" 
de Grupos de Google.
Para anular la suscripción a este grupo y dejar de recibir sus mensajes, envía 
un correo electrónico a [email protected].
Para obtener más opciones, visita https://groups.google.com/d/optout.

Responder a