Преобразовать объект Entity Framework в объект JSON - PullRequest
3 голосов
/ 24 октября 2011

Я пытаюсь заставить общий обработчик публиковать объект JSONJ на основе моего типа сущности SYSTEM_AUDIT_SHEET:

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'.

101 * * * * * * * * *

Ответы [ 2 ]

1 голос
/ 24 октября 2011

Возможно, проблема в том, что ваш 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));

Свойства Id и Title будут сопоставлены непосредственно от SYSTEM_AUDIT_SHEET до JSON_SYSTEM_AUDIT_SHEET, поскольку они имеют одинаковые имена в обоих типах.Свойство SomeOtherAuditSheetsId требует специальной настройки, поскольку в типе источника нет свойства с таким точным именем.

Когда вы хотите преобразовать SYSTEM_AUDIT_SHEET в JSON_SYSTEM_AUDIT_SHEET, вы делаете:

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

Вывозможно, стоит взглянуть на функции выравнивания AutoMapper .

Надеюсь, это поможет.

1 голос
/ 24 октября 2011

Вы не можете преобразовать объекты в 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". Смотрите две верхние ссылки переполнения стека.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...