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

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

问题描述

我收到一个循环引用序列化错误,但是据我所知,我没有任何循环引用。我从数据库中检索一组订单,并将其作为JSON发送到客户端。所有代码如下所示。



这是错误:


错误



在序列化类型为
'System.Data.Entity.DynamicProxies的对象时,检测到
的循环引用。 Order_83CECF2AA4DE38232F9077D4B26941AB96BC61230419EA8AC42C9100E6072812' 。
描述:执行
当前Web请求期间发生未处理的异常
。请查看
堆栈跟踪以获取有关
错误的更多信息,以及它在
中的代码。

异常详细信息:
System.InvalidOperationException:检测到
循环引用,而
序列化
' System.Data.Entity.DynamicProxies.Order_83CECF2AA4DE38232F9077D4B26941AB96BC61230419EA8AC42C9100E6072812'。



源错误:



生成未处理的异常
在执行当前的
Web请求期间。有关
起始点和异常位置的信息
可以使用以下异常
堆栈跟踪来识别。


我的课程如下:



订单

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

public int PatientId {get;组; }
public virtual患者病人{get;组; }

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

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

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

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

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

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

public DateTime ApprovalDate {get;组; }

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

患者

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

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

public bool IsDeprecated {get;组;
}

认证期

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

代理商

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

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

诊断

  public class Diagnosis 
{
[Key]
public int DiagnosisId {get;组; }
public string Icd9Code {get;组; }
public string描述{get;组; }
public DateTime DateOfDiagnosis {get;组; }
public string Onset {get;组; }
public string Details {get;组;
}

OrderApprovalStatus

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

用户

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

}




注意:地址类是编辑期间的新添加


地址

  public class Address 
{
[Key]
public int AddressId {get;组; }
public string StreetAddress {get;组; }
public string City {get;组; }
public string State {get;组; }
public string Zip {get;组; }
public string Phone {get;组; }
public string标题{get;组; }
public string Label {get;组;
}

执行序列化的代码在这里:



OrderController摘录

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

感谢

解决方案

您可以尝试从所有导航属性中删除 virtual 关键字,以禁用延迟加载和代理创建,然后使用加载加载来加载明确要求的对象图:

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

参考您的上一篇文章看起来你的应用程序不依赖于延迟加载,因为你在那里引入了虚拟属性,懒惰地加载对象图,可能导致序列化问题。



修改



没有必要从导航属性中删除 virtual 关键字(这将使懒惰加载完全不可能的模型)。对于代理令人不安的特定情况(如序列化),可以禁用代理创建(它会禁用延迟加载):

  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 - 代码优先 - JSON循环引用序列化错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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