Как избежать циклической ссылки при сериализации класса Entity Framework - PullRequest
1 голос
/ 14 декабря 2010

У меня есть приложение MVC-3 (RC1), использующее Entity Framework 4.

Я хочу вернуть объект JSON из действия контроллера.На этот объект ссылаются другие объекты, которые, очевидно, возвращают ссылку.

Таким образом, я получаю следующую ошибку циклической ссылки:

Ошибка сервера в приложении '/'.

При сериализации объекта типа «Application.Models.ReferenceObject» была обнаружена циклическая ссылка.

Описание: во время выполнения текущего веб-запроса произошло необработанное исключение.Пожалуйста, просмотрите трассировку стека для получения дополнительной информации об ошибке и о том, где она возникла в коде.

Сведения об исключении: System.InvalidOperationException: при сериализации объекта типа 'Application.Models.ReferenceObject' обнаружена циклическая ссылка.

NB: Приложение & ReferenceObject , очевидно, является заменой действительного пространства имен / объекта.

Согласно Переполнение стека: исключение циклической ссылки при сериализации LINQ для классов SQL , это можно преодолеть с помощьюJSON.Net;однако я хотел бы избежать этого и вместо этого попытаться исключить неправильные ссылочные свойства из сериализуемого объекта.

Что я имею в виду?

Я хочу сделать что-то вроде этого:

IList<ReferenceObject> list = Repository.GetReferenceObjects();
return Json(list.**<method>**("ObjectsReferencingThis"));

, где **<method>** - это некоторый метод, который противоположен методу ObjectQuery(Of T).Include, а ObjectsReferencingThis - это свойство, которое вызывает циклическую ссылку.

NB: Я не хочу удалять эти свойства или создавать POCO, поскольку это влияет только на сериализацию Json.

Кто-нибудь может помочь, пожалуйста?

:)

Ответы [ 2 ]

2 голосов
/ 14 декабря 2010

У меня была похожая проблема, когда я работал над одним из моих предыдущих проектов.Вот что я в итоге сделал:

IList<Product> list = Repository.GetProducts();
  var collection = products.Select(product => new
        {
            id = product.Id,
            name = product.Name,
            detailUrl = product.DetailUrl,
            imageLargeUrl = product.ThumbNailUrl,
            tagtitle = product.Name.ToUpper(),
            tagheader = "Words our cherished patrons use to describe this product",
            tagwords = from tag in product.Tags group tag by tag.Name into words select new { name =          words.Key, weight = words.Count() }
        });

 var result = new {id = inquiry.Id, products = collection, };
 return this.Jsonp(result);

Вот как будет выглядеть результат Json:

{
"id" : 2,
"products" : [{
    "id" : "3605970008857",
    "name" : "TITLE1",
    "detailUrl" : "http://www.urlhere.com",
    "tagwords" : [{
        "name" : "roses",
        "weight" : 1
    },
    {
        "name" : "cotton",
        "weight" : 1
    },
    {
        "name" : "happy",
        "weight" : 1
    }]
},
{
    "id" : "3605970019891",
    "name" : "TITLE2",
    "detailUrl" : "http://www.urlhere.com",
    "tagwords" : []
}],

}

Вы также можете добавить другие свойстваот того, что вы указали объекты в результате, как вы хотите, чтобы они отображались в вашем объекте Json:)

0 голосов
/ 26 сентября 2016

Я сделал очень тривиальное решение, которое не рекомендуется, если у вас очень большой список

letters=UserOperations.GetDepartmentLettersForSecretary(pageNumber, pageSize,(Session["User"] as User).DepartmentID.Value, (Session["User"] as User).ID);

foreach (Letter letter in letters)
{
    letter.LetterStatus.Letters = null;
}

, проблема circular reference в моем случае - в LetterStatus.*

, как я уже сказал, его not recommended, если у вас есть very big list

...