将实体框架对象图序列化为 Json 时防止 StackOverflowException [英] Preventing StackOverflowException while serializing Entity Framework object graph into Json

查看:23
本文介绍了将实体框架对象图序列化为 Json 时防止 StackOverflowException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想序列化一个 ),因为这会引入非常长且难以维护的代码片段).

解决方案

您有相互矛盾的顾虑,EF 模型针对将您的数据模型存储在 RDBMS 中进行了优化,而不是用于序列化 - 这就是具有单独 DTO 的作用.否则,您的客户端将绑定到您的数据库,而您的数据模型的每一次更改都有可能破坏您现有的服务客户端.

话虽如此,正确的做法是维护您映射到的独立 DTO,这些 DTO 定义了您希望模型从外部世界看起来像的所需形状(又名线格式).

ServiceStack.Common 包括内置映射函数(即 TranslateTo/PopulateFrom),可简化将实体映射到 DTO,反之亦然-相反.这是一个示例:

https://groups.google.com/d/msg/servicestack/BF-egdVm3M8/0DXLIeDoVJEJ

另一种方法是使用 [DataContract]/[DataMember] 字段装饰要在数据模型上序列化的字段.任何不属于 [DataMember] 的属性都不会被序列化 - 因此您可以使用它来隐藏导致 StackOverflowException 的循环引用.

I want to serialize an Entity Framework Self-Tracking Entities full object graph (parent + children in one to many relationships) into Json.

For serializing I use ServiceStack.JsonSerializer.

This is how my database looks like (for simplicity, I dropped all irrelevant fields):

I fetch a full profile graph in this way:

public Profile GetUserProfile(Guid userID)
{
    using (var db = new AcmeEntities())
    {
        return db.Profiles.Include("ProfileImages").Single(p => p.UserId == userId);
    }
}

The problem is that attempting to serialize it:

Profile profile = GetUserProfile(userId);
ServiceStack.JsonSerializer.SerializeToString(profile);

produces a StackOverflowException. I believe that this is because EF provides an infinite model that screws the serializer up. That is, I can techincally call: profile.ProfileImages[0].Profile.ProfileImages[0].Profile ... and so on.

How can I "flatten" my EF object graph or otherwise prevent ServiceStack.JsonSerializer from running into stack overflow situation?

Note: I don't want to project my object into an anonymous type (like these suggestions) because that would introduce a very long and hard-to-maintain fragment of code).

解决方案

You have conflicting concerns, the EF model is optimized for storing your data model in an RDBMS, and not for serialization - which is what role having separate DTOs would play. Otherwise your clients will be binded to your Database where every change on your data model has the potential to break your existing service clients.

With that said, the right thing to do would be to maintain separate DTOs that you map to which defines the desired shape (aka wireformat) that you want the models to look like from the outside world.

ServiceStack.Common includes built-in mapping functions (i.e. TranslateTo/PopulateFrom) that simplifies mapping entities to DTOs and vice-versa. Here's an example showing this:

https://groups.google.com/d/msg/servicestack/BF-egdVm3M8/0DXLIeDoVJEJ

The alternative is to decorate the fields you want to serialize on your Data Model with [DataContract] / [DataMember] fields. Any properties not attributed with [DataMember] wont be serialized - so you would use this to hide the cyclical references which are causing the StackOverflowException.

这篇关于将实体框架对象图序列化为 Json 时防止 StackOverflowException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆