EF 4.1 - code首先 - JSON循环引用序列化错误 [英] EF 4.1 - Code First - JSON Circular Reference Serialization Error

查看:260
本文介绍了EF 4.1 - code首先 - JSON循环引用序列化错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我得到一个循环引用序列化错误,虽然,据我所知,我没有任何循环引用。我从数据库中检索一组订单,并将它们发送到客户端为JSON。所有code如下图所示。

这是错误:


  

错误


  
  

中检测到循环引用
  而序列化类型的对象
  'System.Data.Entity.DynamicProxies.Order_83CECF2AA4DE38232F9077D4B26941AB96BC61230419EA8AC42C9100E6072812'.
  说明:未处理的异常
  的执行过程中发生
  当前Web请求。请检查
  堆栈跟踪有关的详细信息
  该错误以及它起源于
  在code。


  
  

异常详细信息:
  System.InvalidOperationException:一
  而检测到循环引用
  序列类型的对象
  'System.Data.Entity.DynamicProxies.Order_83CECF2AA4DE38232F9077D4B26941AB96BC61230419EA8AC42C9100E6072812'.


  
  

源错误:


  
  

生成了未处理的异常
  当前的执行过程中
  Web请求。关于信息
  例外的起源和地点
  可以使用异常被识别
  堆栈跟踪的下面。


我的课程如下:

订单

 公共类订单
{
    [键]
    公众诠释的OrderId {搞定;组; }    公众诠释PatientId {搞定;组; }
    公共虚拟病人患者{搞定;组; }    公众诠释CertificationPeriodId {搞定;组; }
    公共虚拟CertificationPeriod CertificationPeriod {搞定;组; }    公众诠释AgencyId {搞定;组; }
    公共虚拟代理机构{搞定;组; }    公众诠释PrimaryDiagnosisId {搞定;组; }
    公共虚拟诊断PrimaryDiagnosis {搞定;组; }    公众诠释ApprovalStatusId {搞定;组; }
    公共虚拟OrderApprovalStatus审核状态{搞定;组; }    公众诠释ApproverId {搞定;组; }
    公共虚拟用户审批{搞定;组; }    公众诠释SubmitterId {搞定;组; }
    公共虚拟用户发布{搞定;组; }    公众的DateTime ApprovalDate {搞定;组; }    公众的DateTime SubmittedDate {搞定;组; }
    公共布尔ISDE $ P $ {pcated获得;组; }
}

耐心

 公共类病人
{
    [键]
    公众诠释PatientId {搞定;组; }
    公共字符串名字{获得;组; }
    公共字符串名字{获得;组; }
    公共字符串MiddleInitial {搞定;组; }
    公共BOOL IsMale;
    公众的DateTime DATEOFBIRTH {搞定;组; }    公众诠释PatientAddressId {搞定;组; }
    公共广播PatientAddress {搞定;组; }    公共BOOL ISDE $ P $ {pcated获得;组; }
}

认证周期

 公共类CertificationPeriod
{
    [键]
    公众诠释CertificationPeriodId {搞定;组; }
    公众的DateTime的startDate {搞定;组; }
    公共DateTime的结束日期{搞定;组; }
    公共BOOL ISDE $ P $ {pcated获得;组; }
}

代理商

 公共类机构
{
    [键]
    公众诠释AgencyId {搞定;组; }
    公共字符串名称{;组; }    公众诠释PatientAddressId {搞定;组; }
    公共虚拟地址地址{搞定;组; }
}

诊断

 公共类诊断
{
    [键]
    公众诠释DiagnosisId {搞定;组; }
    公共字符串ICD9 code {搞定;组; }
    公共字符串描述{搞定;组; }
    公众的DateTime DateOfDiagnosis {搞定;组; }
    公共字符串发病{搞定;组; }
    公共字符串详细信息{获得;组; }
}

OrderApprovalStatus

 公共类OrderApprovalStatus
{
    [键]
    公众诠释OrderApprovalStatusId {搞定;组; }
    公共字符串状态{搞定;组; }
}

用户

 公共类用户
{
    [键]
    公众诠释用户ID {搞定;组; }
    公共字符串登录{搞定;组; }
    公共字符串名字{获得;组; }
    公共字符串名字{获得;组; }
    公共字符串NPI {搞定;组; }
    公共字符串电子邮件{获得;组; }}


  

注意:Address类新增加的过程中修改


地址

 公共类地址
{
    [键]
    公众诠释AddressId {搞定;组; }
    公共字符串的StreetAddress {搞定;组; }
    公共字符串城{搞定;组; }
    公共字符串状态{搞定;组; }
    公共字符串邮编{搞定;组; }
    公共字符串电话{搞定;组; }
    公共字符串名称{搞定;组; }
    公共字符串标签{搞定;组; }
}

在code执行该序列化是在这里:

从OrderController摘录

 公众的ActionResult GETALL()
    {
        返回JSON(ppEFContext.Orders,JsonRequestBehavior.AllowGet);
    }

感谢


解决方案

您可以尝试从所有导航属性中删除虚拟关键字禁用延迟加载和代理的创建和然后用预先加载而不是显式地加载所需的对象图:

 公众的ActionResult GETALL()
{
    返回JSON(ppEFContext.Orders
                           .INCLUDE(O => o.Patient)
                           .INCLUDE(O => o.Patient.PatientAddress)
                           .INCLUDE(O => o.CertificationPeriod)
                           .INCLUDE(O => o.Agency)
                           .INCLUDE(O => o.Agency.Address)
                           .INCLUDE(O => o.PrimaryDiagnosis)
                           .INCLUDE(O => o.ApprovalStatus)
                           .INCLUDE(O => o.Approver)
                           .INCLUDE(O => o.Submitter)
        JsonRequestBehavior.AllowGet);
}

参照您的<一个href=\"http://stackoverflow.com/questions/5585359/how-to-get-full-object-with-$c$c-first-entity-framework-4-1\">$p$pvious帖子它看起来像你的应用程序不依赖于延迟加载,因为反正你介绍那里的虚拟财产懒洋洋地加载的对象图,现在可能造成系列化的麻烦。

修改

这是没有必要从导航属性(这将使延迟加载完全不可能的型号)删除虚拟关键字。这足以为那里代理是令人不安的具体情况禁用代理的创建(即禁用延迟加载为好),如序列化:

  ppEFContext.Configuration.ProxyCreationEnabled = FALSE;

这禁用只针对特定的上下文实例代理的创建 ppEFContext

(我刚刚看到,@WillC已经在这里提到它。给予好评的此编辑,请给他的回答。)

I am getting an a Circular Reference Serialization Error although, to my knowledge I do not have any circular references. I am retrieving a set of Orders from the database and sending them to the client as JSON. All the code is shown below.

This is the error:

Error

A circular reference was detected while serializing an object of type 'System.Data.Entity.DynamicProxies.Order_83CECF2AA4DE38232F9077D4B26941AB96BC61230419EA8AC42C9100E6072812'. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.InvalidOperationException: A circular reference was detected while serializing an object of type 'System.Data.Entity.DynamicProxies.Order_83CECF2AA4DE38232F9077D4B26941AB96BC61230419EA8AC42C9100E6072812'.

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

My classes are as follows:

Order

public class Order
{
    [Key]
    public int OrderId { get; set; }

    public int PatientId { get; set; }
    public virtual Patient Patient { get; set; }

    public int CertificationPeriodId { get; set; }
    public virtual CertificationPeriod CertificationPeriod { get; set; }

    public int AgencyId { get; set; }
    public virtual Agency Agency { get; set; }

    public int PrimaryDiagnosisId { get; set; }
    public virtual Diagnosis PrimaryDiagnosis { get; set; }

    public int ApprovalStatusId { get; set; }
    public virtual OrderApprovalStatus ApprovalStatus { get; set; }

    public int ApproverId { get; set; }
    public virtual User Approver { get; set; }

    public int SubmitterId { get; set; }
    public virtual User Submitter { get; set; }

    public DateTime ApprovalDate { get; set; }

    public DateTime SubmittedDate { get; set; }
    public Boolean IsDeprecated { get; set; }
}

Patient

public class Patient
{
    [Key]
    public int PatientId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string MiddleInitial { get; set; }
    public bool IsMale;
    public DateTime DateOfBirth { get; set; }

    public int PatientAddressId { get; set; }
    public Address PatientAddress { get; set; }

    public bool IsDeprecated { get; set; }
}

Certification Period

public class CertificationPeriod
{
    [Key]
    public int CertificationPeriodId { get; set; }
    public DateTime startDate { get; set; }
    public DateTime endDate { get; set; }
    public bool isDeprecated { get; set; }
}

Agency

public class Agency
{
    [Key]
    public int AgencyId { get; set; }
    public string Name { get; set; }

    public int PatientAddressId { get; set; }
    public virtual Address Address { get; set; }
}

Diagnosis

public class Diagnosis
{
    [Key]
    public int DiagnosisId { get; set; }
    public string Icd9Code { get; set; }
    public string Description { get; set; }
    public DateTime DateOfDiagnosis { get; set; }
    public string Onset { get; set; }
    public string Details { get; set; }
}

OrderApprovalStatus

public class OrderApprovalStatus
{
    [Key]
    public int OrderApprovalStatusId { get; set; }
    public string Status { get; set; }
}

User

public class User
{
    [Key]
    public int UserId { get; set; }
    public string Login { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string NPI { get; set; }
    public string Email { get; set; }

}

NOTE: ADDRESS CLASS IS NEW ADDITION DURING EDIT

Address

public class Address
{
    [Key]
    public int AddressId { get; set; }
    public string StreetAddress { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string Zip { get; set; }
    public string Phone { get; set; }
    public string Title { get; set; }
    public string Label { get; set; }
}

The code that executes the serialization is here:

Excerpt from OrderController

    public ActionResult GetAll()
    {
        return Json(ppEFContext.Orders, JsonRequestBehavior.AllowGet);
    }

Thanks

解决方案

You could try to remove the virtual keyword from all navigation properties to disable lazy loading and proxy creation and then use eager loading instead to load the required object graph explicitely:

public ActionResult GetAll()
{
    return Json(ppEFContext.Orders
                           .Include(o => o.Patient)
                           .Include(o => o.Patient.PatientAddress)
                           .Include(o => o.CertificationPeriod)
                           .Include(o => o.Agency)
                           .Include(o => o.Agency.Address)
                           .Include(o => o.PrimaryDiagnosis)
                           .Include(o => o.ApprovalStatus)
                           .Include(o => o.Approver)
                           .Include(o => o.Submitter),
        JsonRequestBehavior.AllowGet);
}

Referring to your previous post it looks like your application isn't relying on lazy loading anyway because you introduced there the virtual properties to load the object graph lazily, possibly causing now the serialization trouble.

Edit

It's not necessary to remove the virtual keyword from the navigation properties (which would make lazy loading completely impossible for the model). It's enough to disable proxy creation (which disables lazy loading as well) for the specific circumstances where proxies are disturbing, like serialization:

ppEFContext.Configuration.ProxyCreationEnabled = false;

This disables proxy creation only for the specific context instance ppEFContext.

(I've just seen, @WillC already mentioned it here. Upvote for this edit please to his answer.)

这篇关于EF 4.1 - code首先 - JSON循环引用序列化错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆