将实体框架对象转换为JSON对象

时间:2011-10-24 13:30:05

标签: c# asp.net json entity-framework

我正在尝试根据我的实体类型SYSTEM_AUDIT_SHEET发布一个JSONJ对象的通用处理程序:

SYSTEM_AUDIT_SHEET sheet = ctx.SYSTEM_AUDIT_SHEET
                              .Where(s => s.SYSTEM_KEY == system_key_dec)
                              .Select(s => s)
                              .OrderByDescending(s => s.AUDIT_SHEET_VERSION)
                              .First();

HttpContext.Current.Response.Write(serializer.Serialize(sheet));

但是我收到以下错误:

  

在序列化类型的对象时检测到循环引用   'System.Data.Entity.DynamicProxies.SYSTEM_AUDIT_SHEET_521A7B786A51FC0F83641182DD72C8DFE6C082418D30BBB977B403409A74CE17'。

为什么我不能将实体转换为JSON?

2 个答案:

答案 0 :(得分:1)

您无法将对象转换为引用自身的json,因为这会创建一个无限长的json字符串。

例如,以下伪代码无效,因为它设置了循环引用(Dog>> Bone>> Dog ...):

class Dog {
    private Bone myBone;
    public Dog() {
        myBone = new Bone(this);
    }
}

class Bone {
    private Dog buriedBy;
    public Bone(Dog d) {
        buriedBy = d;
    }
}

通过谷歌搜索“json循环引用”似乎有一些很好的解决方案。请参阅前两个堆栈溢出链接。

答案 1 :(得分:1)

问题可能是您的SYSTEM_AUDIT_SHEET包含引用类型SYSTEM_AUDIT_SHEET的实例的属性,或者它包含指向具有指向SYSTEM_AUDIT_SHEET实例的指针的对象的属性。序列化这样一个指针圈会导致序列化过程永远不会结束。

在进行序列化之前,您需要将SYSTEM_AUDIT_SHEET转换为不(直接或间接)引用自身的类型。您可以创建一个全新类型并编写代码以从SYSTEM_AUDIT_SHEET实例化此类型(AutoMapper可能会派上用场)。但是,我倾向于发现在大多数情况下使用匿名类型更容易:

SYSTEM_AUDIT_SHEET sheet = /*some sheet*/
var json = new {
  sheet.Id,
  sheet.RevisionNumber,
  sheet.Title
};
return serializer.Serialize(json);

修改

如果您想使用AutoMapper并假设您的工作表看起来像

class SYSTEM_AUDIT_SHEET 
{
    public int Id { get; set; }
    public SYSTEM_AUDIT_SHEET SomeOtherAuditSheet { get;set;}
    public string Title { get;set;}
}

您可以创建类似

的类型
class JSON_SYSTEM_AUDIT_SHEET
{
    public int Id { get; set; }
    public int SomeOtherAuditSheetsId { get;set;}
    public string Title { get;set;}
}

当您的应用程序启动时(例如,在Application_Start中),您可以配置AutoMapper:

AutoMapper.Mapper.CreateMap<SYSTEM_AUDIT_SHEET, JSON_SYSTEM_AUDIT_SHEET>()
  .ForMember(dest => dest.SomeOtherAuditSheetsId, opt => opt.MapFrom(src => src.SomeOtherAuditSheet.Id));

IdTitle属性将直接映射到SYSTEM_AUDIT_SHEETJSON_SYSTEM_AUDIT_SHEET,因为它们在两种类型中都具有相同的名称。属性SomeOtherAuditSheetsId需要特殊配置,因为源类型上没有具有该确切名称的属性。

如果您想将SYSTEM_AUDIT_SHEET转换为JSON_SYSTEM_AUDIT_SHEET,请执行以下操作:

return AutoMapper.Mapper.Map<SYSTEM_AUDIT_SHEET , JSON_SYSTEM_AUDIT_SHEET >(sheet);

您可能需要查看AutoMapper's flattening features

希望这有帮助。