在序列化Entity Framework类时,如何避免循环引用

时间:2010-12-14 05:59:05

标签: entity-framework-4 asp.net-mvc-3 objectquery

我有一个使用Entity Framework 4的MVC-3(RC1)应用程序。

我希望从控制器操作返回一个JSON对象。此对象由其他对象引用,显然会返回引用。

因此我收到以下循环引用错误:

  应用程序中的服务器错误。

     

检测到循环参考   在序列化类型的对象时   'Application.Models.ReferenceObject'。

     

描述:未处理的异常   在执行期间发生   当前的网络请求。请查看   堆栈跟踪以获取更多信息   错误及其来源   代码。

     

异常详细信息:   System.InvalidOperationException:A   检测到循环引用   序列化类型的对象   'Application.Models.ReferenceObject'。

注意:应用& ReferenceObject 显然是实际命名空间/对象的替代。

根据Stack Overflow: Circular reference exception when serializing LINQ to SQL classes,这可以使用JSON.Net来克服;但是我想避免这种情况,而是尝试从被序列化的对象中排除有问题的引用属性。

我的意思是什么?

我想做这样的事情:

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

其中**<method>**是与ObjectQuery(Of T).Include方法相反的方法,而ObjectsReferencingThis是导致循环引用的属性。

NB:我不希望删除这些属性或创建POCO,因为这只会影响Json序列化。

有人能帮忙吗?

:)

2 个答案:

答案 0 :(得分:2)

我在上一个项目中遇到过类似的问题。 这是我最终做的事情:

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对象中显示:)

答案 1 :(得分:0)

我提出了一个非常简单的解决方案,如果您有非常大的列表

,建议不要这样做
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.Letters中 所以我Iterated through the listassigned it to null

正如我告诉你的not recommended,如果你有very big list