将 nHibernate 查询序列化为 JSON
在深入研究 Fluent nHibernate 时,我发现了使用它的潜在破坏者......
给出以下 POCO 代码。
public class Customer
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual Details Details { get; set; }
}
public class Details
{
public virtual int Id { get; set; }
public virtual IList<Orders> Orders { get; set; }
}
public class CustomerMap : ClassMap<Customer>
{
// perform mapping
}
public class DetailsMap : ClassMap<Details>
{
// perform mapping
}
我加载了 ASP.NET MVC 并尝试使用 Json 序列化。
using System.Web.Script.Serialization;
public static partial class JsonExtensions
{
public static string ToJson(this object item)
{
return new JavaScriptSerializer().Serialize(item);
}
}
Lo,当我将查询从 nHibernate 上下文传递到 ToJson 方法时,我收到了错误!
序列化“System.Reflection.RuntimeModule”类型的对象时检测到循环引用。
无论我拉单个对象,还是对象列表......或任何与此相关的东西,它似乎都会这样做。我什至尝试将我的类标记为 [Serialized]
,结果相同。使用 Microsoft Entity Framework Code-Only 方法的完全相同的类不会发生这种情况。
我可以不将 nHibernate DTO 反序列化为 JSON 吗?
添加更多代码以供检查。
using (var session = sessionFactory.OpenSession())
{
using (var transaction = session.BeginTransaction())
{
var customers= session.CreateCriteria(typeof(Customer)).List<Customer>();
foreach (var customer in customers)
{
Console.WriteLine(customer.ToJson());
}
Console.ReadLine();
}
}
In delving into Fluent nHibernate, I discovered a potential breaker for using it...
Given the following POCO code.
public class Customer
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual Details Details { get; set; }
}
public class Details
{
public virtual int Id { get; set; }
public virtual IList<Orders> Orders { get; set; }
}
public class CustomerMap : ClassMap<Customer>
{
// perform mapping
}
public class DetailsMap : ClassMap<Details>
{
// perform mapping
}
I loaded up ASP.NET MVC and attempted to use Json Serialization.
using System.Web.Script.Serialization;
public static partial class JsonExtensions
{
public static string ToJson(this object item)
{
return new JavaScriptSerializer().Serialize(item);
}
}
And Lo, when I passed a query from my nHibernate context to the ToJson
method, I got an error!
A circular reference was detected while serializing an object of type 'System.Reflection.RuntimeModule'.
It seems to do this whether I pull a single object, or a list of objects ..or anything for that matter. I've even tried marking my classes as [Serializable]
with the same result. This doesn't happen with the exact same classes using the Microsoft Entity Framework Code-Only approach.
Can I not deserialize nHibernate DTOs into JSON?
Adding more code for examination.
using (var session = sessionFactory.OpenSession())
{
using (var transaction = session.BeginTransaction())
{
var customers= session.CreateCriteria(typeof(Customer)).List<Customer>();
foreach (var customer in customers)
{
Console.WriteLine(customer.ToJson());
}
Console.ReadLine();
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这只是一种预感,但您可能想调查一下它真正尝试序列化的类型 - nHibernate 在运行时为每个 POCO 生成代理(因此它可以执行诸如延迟加载外键实体等操作)。这可能就是您收到此错误的原因。
尝试指定要序列化的确切类型,或者创建一个全新的要序列化的对象,用 nHibernate POCO 的属性填充其属性。
编辑:
这似乎更能解决您的问题:
http://www. west-wind.com/WebLog/posts/147218.aspx
基本上,检查所有 POCO 是否有任何循环引用(例如,具有 Order POCO 作为属性的 Customer POCO,而 Order POCO 具有 Customer's 列表)作为财产)
This is just a hunch but you might like to investigate what type it is really trying to serialize- nHibernate generates proxies for each POCO at runtime (so it can do stuff like lazy loading of foreign key entities, etc.). This may be why you are getting this error.
Try specifying the exact type to be serialized or perhaps create a brand new object to serialize, populating its properties with that of the nHibernate POCO.
EDIT:
This seems to be much more likley the answer to your problems:
http://www.west-wind.com/WebLog/posts/147218.aspx
Basically, check all of your POCO's for any circular references (e.g. a Customer POCO that has an Order POCO as a property while the Order POCO has a list of Customer's as a property)