c#-4.0 - 在将 Entity Framework 对象图序列化为 Json 时防止 StackOverflowException

标签 c#-4.0 entity-framework-4 self-tracking-entities servicestack jsonserializer

我想序列化一个 Entity Framework Self-Tracking Entities将完整的对象图(一对多关系中的父+子)转换为Json。

对于序列化,我使用 ServiceStack.JsonSerializer .

这就是我的数据库的样子(为简单起见,我删除了所有不相关的字段):

ERD

我以这种方式获取完整的个人资料图:

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

问题是试图序列化它:
Profile profile = GetUserProfile(userId);
ServiceStack.JsonSerializer.SerializeToString(profile);

产生 StackOverflowException .
我相信这是因为 EF 提供了一个无限模型,将序列化器搞砸了。也就是说,我可以在技术上调用:profile.ProfileImages[0].Profile.ProfileImages[0].Profile ...等等。

如何“展平”我的 EF 对象图或以其他方式阻止 ServiceStack.JsonSerializer 从遇到堆栈溢出的情况?

注意:我不想将我的对象投影到匿名类型(如 these suggestions ),因为这会引入非常长且难以维护的代码片段)。

最佳答案

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

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

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

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

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

关于c#-4.0 - 在将 Entity Framework 对象图序列化为 Json 时防止 StackOverflowException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9150920/

相关文章:

c# - 是否使用 "Optional, DefaultParameterValue"属性?

c# - 如何在 .NET 中引用特定的基类方法?

c# - N 层应用程序上的 Entity Framework 自跟踪实体

wcf - EF4 自跟踪实体和 WCF 序列化导致堆栈溢出

css - ASP Repeater - 无法在 DIV 中添加类

c# - 为什么协变和逆变不支持值类型

entity-framework - Poco+Entity Framework 4. 我应该在哪里添加使用 Poco 类的方法?

c# - 如何从 C# Entity Framework Code First 模型获取 mysql char 列类型

c# - 应用程序从 EF4 迁移到 Dapper.net