尽管据我所知我没有任何循环引用,但是我遇到了循环引用序列化错误。我正在从数据库中检索一组订单,并将它们作为JSON发送到客户端。所有代码如下所示。
这是错误:
错误 序列化类型为’System.Data.Entity.DynamicProxies.Order_83CECF2AA4DE38232F9077D4B26941AB96BC61230419EA8AC42C9100E6072812’的对象时,检测到循环引用。说明:执行当前Web请求期间发生未处理的异常。请查看堆栈跟踪,以获取有关错误及其在代码中起源的更多信息。 异常详细信息:System.InvalidOperationException:序列化类型为’System.Data.Entity.DynamicProxies.Order_83CECF2AA4DE38232F9077D4B26941AB96BC61230419EA8AC42C9100E6072812’的对象时,检测到循环引用。 源错误: 当前Web请求的执行期间生成了未处理的异常。可以使用下面的异常堆栈跟踪来标识有关异常的来源和位置的信息。
错误
序列化类型为’System.Data.Entity.DynamicProxies.Order_83CECF2AA4DE38232F9077D4B26941AB96BC61230419EA8AC42C9100E6072812’的对象时,检测到循环引用。说明:执行当前Web请求期间发生未处理的异常。请查看堆栈跟踪,以获取有关错误及其在代码中起源的更多信息。
异常详细信息:System.InvalidOperationException:序列化类型为’System.Data.Entity.DynamicProxies.Order_83CECF2AA4DE38232F9077D4B26941AB96BC61230419EA8AC42C9100E6072812’的对象时,检测到循环引用。
源错误:
当前Web请求的执行期间生成了未处理的异常。可以使用下面的异常堆栈跟踪来标识有关异常的来源和位置的信息。
我的课程如下:
订购
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; } }
患者
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; } }
认证期限
public class CertificationPeriod { [Key] public int CertificationPeriodId { get; set; } public DateTime startDate { get; set; } public DateTime endDate { get; set; } public bool isDeprecated { get; set; } }
机构
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; } }
诊断
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; } }
用户
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; } }
注意:地址类别是编辑过程中的新添加
地址
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; } }
执行序列化的代码在这里:
摘自OrderController
public ActionResult GetAll() { return Json(ppEFContext.Orders, JsonRequestBehavior.AllowGet); }
谢谢
您可以尝试virtual从所有导航属性中删除关键字以禁用延迟加载和代理创建,然后使用快速加载来显式加载所需的对象图:
virtual
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); }
参考您以前的文章,您的应用程序似乎也不依赖于延迟加载,因为您在那里引入了虚拟属性来延迟加载对象图,这可能会导致序列化麻烦。
编辑
不必virtual从导航属性中删除关键字(这将使模型完全无法进行延迟加载)。在代理受干扰的特定情况下(例如序列化),禁用代理创建(也将禁用延迟加载)就足够了:
ppEFContext.Configuration.ProxyCreationEnabled = false;
这仅对特定的上下文实例禁用代理创建ppEFContext。
ppEFContext
(我刚刚看过,@ WillC在这里已经提到过。请对此答案表示支持。)