Hay alguien utilizando JSON.NET con NHibernate? Noté que recibo errores cuando intento cargar una clase con colecciones secundarias.JSON.NET y NHibernate Lazy Loading Colecciones de
Respuesta
¿Usted está consiguiendo una dependencia-circular error? ¿Cómo ignoras los objetos de la serialización?
Dado que la carga diferida genera un proxy de objetos, cualquier atributo de clase sus miembros han se perderán. Me encontré con el mismo problema con Newtonsoft JSON-serializer, ya que el proxy-objeto ya no tenía los atributos [JsonIgnore].
Vea las respuestas de Mine y Handcraftsman, contienen una solución para exactamente este problema. – Liedman
Tipo de voto retrasado para votar una respuesta que fue escrita 1,5 años antes que la tuya? – jishi
Sí, ese es exactamente el problema con el que me estaba encontrando. Sin embargo, no había estado ignorando ningún objeto de la serialización cuando estaba recibiendo los errores. ¡Creo que necesito volver y leer los documentos correctamente! – user32326
Es probable que desee a la carga ansiosa la mayor parte del objeto de modo que se puede serializar:
ICriteria ic = _session.CreateCriteria(typeof(Person));
ic.Add(Restrictions.Eq("Id", id));
if (fetchEager)
{
ic.SetFetchMode("Person", FetchMode.Eager);
}
Una buena manera de hacer esto es añadir un bool al constructor (bool isFetchEager) de sus datos método del proveedor.
utilizo NHibernate con Json.NET y se dio cuenta que estaba recibiendo "__interceptors" inexplicables propiedades en mis objetos serializados. Una búsqueda en google apareció this excellent solution por Lee Henson que adapté para trabajar con Json.NET 3.5 Release 5 de la siguiente manera.
public class NHibernateContractResolver : DefaultContractResolver
{
private static readonly MemberInfo[] NHibernateProxyInterfaceMembers = typeof(INHibernateProxy).GetMembers();
protected override List<MemberInfo> GetSerializableMembers(Type objectType)
{
var members = base.GetSerializableMembers(objectType);
members.RemoveAll(memberInfo =>
(IsMemberPartOfNHibernateProxyInterface(memberInfo)) ||
(IsMemberDynamicProxyMixin(memberInfo)) ||
(IsMemberMarkedWithIgnoreAttribute(memberInfo, objectType)) ||
(IsMemberInheritedFromProxySuperclass(memberInfo, objectType)));
var actualMemberInfos = new List<MemberInfo>();
foreach (var memberInfo in members)
{
var infos = memberInfo.DeclaringType.BaseType.GetMember(memberInfo.Name);
actualMemberInfos.Add(infos.Length == 0 ? memberInfo : infos[0]);
}
return actualMemberInfos;
}
private static bool IsMemberDynamicProxyMixin(MemberInfo memberInfo)
{
return memberInfo.Name == "__interceptors";
}
private static bool IsMemberInheritedFromProxySuperclass(MemberInfo memberInfo, Type objectType)
{
return memberInfo.DeclaringType.Assembly == typeof(INHibernateProxy).Assembly;
}
private static bool IsMemberMarkedWithIgnoreAttribute(MemberInfo memberInfo, Type objectType)
{
var infos = typeof(INHibernateProxy).IsAssignableFrom(objectType)
? objectType.BaseType.GetMember(memberInfo.Name)
: objectType.GetMember(memberInfo.Name);
return infos[0].GetCustomAttributes(typeof(JsonIgnoreAttribute), true).Length > 0;
}
private static bool IsMemberPartOfNHibernateProxyInterface(MemberInfo memberInfo)
{
return Array.Exists(NHibernateProxyInterfaceMembers, mi => memberInfo.Name == mi.Name);
}
}
Para usarlo, simplemente ponga una instancia en la propiedad ContractResolver de su JsonSerializer. El problema de dependencia circular observado por jishi puede resolverse estableciendo la propiedad ReferenceLoopHandling en ReferenceLoopHandling.Ignore. Aquí es un método de extensión que se puede utilizar para serializar objetos usando Json.Net
public static void SerializeToJsonFile<T>(this T itemToSerialize, string filePath)
{
using (StreamWriter streamWriter = new StreamWriter(filePath))
{
using (JsonWriter jsonWriter = new JsonTextWriter(streamWriter))
{
jsonWriter.Formatting = Formatting.Indented;
JsonSerializer serializer = new JsonSerializer
{
NullValueHandling = NullValueHandling.Ignore,
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
ContractResolver = new NHibernateContractResolver(),
};
serializer.Serialize(jsonWriter, itemToSerialize);
}
}
}
Gracias por este código, ¡funciona genial! Y me salvó de usar una sesión sin estado. –
Esto dejó de funcionar en JSON.NET 3.5 versión 7, pero aún funciona bien en 3.5 versión 5. – zcrar70
parece que han actualizado AssemblyVersion a partir de la versión 6, lo que significa que si incluyó previamente este archivo en su solución, la versión no coincidiría , y lanzar algún tipo de excepción de seguridad. ¿Podría ser ese el caso? – jishi
Hemos tenido este problema exacto, que se resolvió con la inspiración de la respuesta de Handcraftsman aquí.
El problema surge de JSON.NET ser confundido acerca de cómo serializar clases de proxy de NHibernate. Solución: serialice las instancias de proxy como su clase base.
una versión simplificada del código de Handcraftsman dice así:
public class NHibernateContractResolver : DefaultContractResolver {
protected override List<MemberInfo> GetSerializableMembers(Type objectType) {
if (typeof(INHibernateProxy).IsAssignableFrom(objectType)) {
return base.GetSerializableMembers(objectType.BaseType);
} else {
return base.GetSerializableMembers(objectType);
}
}
}
en mi humilde opinión, este código tiene la ventaja de que siguen confiando en el comportamiento por defecto de JSON.NET con respecto a los atributos personalizados, etc. (y el código es mucho ¡corta!).
Se utiliza como esto
var serializer = new JsonSerializer{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
ContractResolver = new NHibernateContractResolver()
};
StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = new Newtonsoft.Json.JsonTextWriter(stringWriter);
serializer.Serialize(jsonWriter, objectToSerialize);
string serializedObject = stringWriter.ToString();
Nota: Este código fue escrito para utilizar con NHibernate y 2.1. Como algunos comentaristas han señalado, no funciona de la caja con las versiones posteriores de NHibernate, tendrá que hacer algunos ajustes. Intentaré actualizar el código si alguna vez tengo que hacerlo con versiones posteriores de NHibernate.
¡Funcionó muy bien para mí! –
No estoy seguro de dónde se usaría este código y cómo. – Ciel
La solución de Liedman ya no funciona porque el tipo pasado es Interfaz, por lo que objectType.BaseType devuelve nulo y se bloquea –
Estaba enfrentando el mismo problema, así que traté de usar el código de @ Liedman, pero nunca me llamaron al GetSerializableMembers()
para la referencia por proxy. he encontrado otro método para anular:
public class NHibernateContractResolver : DefaultContractResolver
{
protected override JsonContract CreateContract(Type objectType)
{
if (typeof(NHibernate.Proxy.INHibernateProxy).IsAssignableFrom(objectType))
return base.CreateContract(objectType.BaseType);
else
return base.CreateContract(objectType);
}
}
+1 - Esta parece ser la única versión que funciona ahora con NH 3.3 y JSON.NET 4.5.7. – TheCloudlessSky
Y probablemente quieras usarlo así: JsonConvert.DefaultSettings =() => nuevos JsonSerializerSettings \t \t \t { \t \t \t \t ContractResolver = new NHibernateContractResolver() \t \t \t}; – PandaWood
En realidad, he intentado esto y no funcionó para mí usando JSON .NET 5,06 y NH 3.3 – PandaWood
Yo diría que este es un problema de diseño en mi opinión. Debido a que NH hace conexiones a la base de datos debajo de todo y tiene proxys en el medio, no es bueno que la transparencia de su aplicación serialice directamente (y como puede ver, a Json.NET no le gustan para nada).
No debe serializar las entidades en sí, pero debe convertirlas en objetos "ver" u objetos POCO o DTO (como quiera que los llame) y luego serializarlos.
La diferencia es que, aunque la entidad NH puede tener proxies, atributos diferidos, etc. Los objetos de vista son objetos simples con solo primitivas que son serializables de manera predeterminada.
¿Cómo administrar FKs? Mi regla personal es:
nivel de las Entidades: clase Person y con una clase de género asociadas
Ver nivel: opinión de la persona con propiedades GenderId y GenderName.
Esto significa que necesita expandir sus propiedades en primitivas al convertir objetos para ver. De esta forma también sus objetos json son más simples y fáciles de manejar.
Cuando necesite insertar los cambios en la base de datos, en mi caso utilizo AutoMapper y realizo una clase ValueResolver que puede convertir su nuevo Guid al objeto Gender.
ACTUALIZACIÓN: Compruebe http://blog.andrewawhitaker.com/blog/2014/06/19/queryover-series-part-4-transforming/ para obtener una vista directa (AliasToBean) de NH. Esto sería un impulso en el lado de DB.
- 1. Lazy Loading en Flexslider
- 2. ¿Qué es Lazy Loading?
- 3. Lazy Loading with Ninject
- 4. jQuery Cycle Lazy Loading
- 5. Android listview lazy loading
- 6. LINQ a las entidades y Lazy Loading
- 7. jQuery Infinite Scrolling/Lazy Loading
- 8. Spring, @Transactional e Hibernate Lazy Loading
- 9. cuándo usar Lazy loading/Eager loading en hibernate?
- 10. EF 4 - Lazy Loading Sin Proxies
- 11. entidad Código Marco Primera Lazy Loading
- 12. Lazy Loading UIImages de archivos sin bloquear el hilo principal?
- 13. colecciones de NHibernate y objetos en movimiento
- 14. DataTable - Lazy Loading Primefaces que muestra el error
- 15. JPA - Force Lazy loading solo para una consulta dada
- 16. NHibernate Eager Cargando colecciones + Paginación
- 17. NHibernate: Actualizando colecciones durante EventListener "PreUpdateEvent"
- 18. Paging sobre una colección-lazy cargado con NHibernate
- 19. Colecciones en cascada usando NHibernate StatelessSession
- 20. Proyecciones NHibernate: cómo proyectar las colecciones
- 21. ¿Cómo desactivo Lazy Loading, Entity Framework 4.1 utilizando código de Migraciones de configuración
- 22. ¿Cuál es el impacto de lazy = "false" en el elemento de clase del mapeo NHibernate?
- 23. Entidad fluida NHibernate HasMany colecciones de diferentes tipos de subclase
- 24. DI y JSON.NET
- 25. Spring @Autowired @ Lazy
- 26. Conocer el recuento de colecciones secundarias sin cargarlas en NHIbernate
- 27. ¿Es el comportamiento predeterminado con Fluent NHibernate para carga lenta HasMany <T> colecciones?
- 28. No persister para: Castle.Proxies. <EntityName> Proxy y lazy = "true" en NHibernate?
- 29. Spring, Hibernate, Blob perez loading
- 30. Entity Framework 4.1 impaciente por defecto loading
¿Puede por favor publicar detalles sobre los errores que está viendo? –
Estaba obteniendo 'El método u operación no está implementado'. y la solución de Liedman funcionó para mí. –