ServiceStack.Text序列化循环引用

2024-04-04

我需要像这样序列化对象图:

public class A
{
     public B Link1 {get;set;}
}

public class B
{
     public A Link2 {get;set;}
}

这样json只得到两个实例,但又被正确反序列化了。例如。使用元 ID 或类似的东西。

我知道 Json.NET 有一种方法,如下所述:http://note.harajuku-tech.org/serializing-circular-references-with-jsonnet http://note.harajuku-tech.org/serializing-circular-references-with-jsonnet带有元 ID。

是否有类似的功能ServiceStack.TextJson 序列化器?

否则,是否可以使用 Json.NETServiceStack如何?

EDIT:

为了清楚起见,我要求提供实例参考,而不仅仅是相同类型。 这方面的一个例子可能是:

[
    {
        "$id": "1",
        "BroId": 0,
        "Name": "John",
        "Bros": [
            {
                "$id": "2",
                "BroId": 0,
                "Name": "Jared",
                "Bros": [
                    {
                        "$ref": "1"
                    }
                ]
            }
        ]
    },
    {
        "$ref": "2"
    }
]

只有 2 个对象“真正”序列化,其余的通过使用$ref财产领域。 想象一个具有子项集合的对象模型。这些子项具有对其父对象的反向引用。例如。客户订单。一个客户有多个订单,每个订单都有对其客户的引用。 现在想想如果您序列化一位客户会发生什么。

Customer
 -> Order
  -> Customer
   -> Order
    -> ...

您会得到类似于该网站名称的结果。 ;)

我真的很喜欢 ServiceStack,因为它的清晰性,而不是要求KnownTypeAttributes etc.

我希望保持它的干净,而不是在我的业务逻辑 pocos 中实现自定义加载器/对象初始化程序。


我通过另一种方式解决了这个问题。这实际上是有效的,但是当使用具有多个循环引用的更复杂的数据结构时,它可能会在以后出现问题。但目前还没有必要。

我尝试添加循环引用功能ServiceStack.Text但发现没有任何开始的意义。也许mythz可以给我一个提示?该功能应该非常容易完成。

我需要该功能来序列化我的数据模型以完全支持NHibernate的合并函数。

我按照神话的建议忽略了属性IgnoreDataMemberAttribute这会导致循环引用。 但这也需要在反序列化后再次重建它们,以使合并功能正常工作。

-> 这就是解决方案,现在按照我的做法进行操作:

我从一个简单的原型开始进行测试,这是一个数据模型

Customer 1->n Orders 1->n OrderDetail.

每个类都派生自实体类。

public class Customer : Entity
{
    public virtual string Name { get; set; }
    public virtual string City { get; set; }
    public virtual IList<Order> Orders { get; set; }
}

public class Order : Entity
{
    public virtual DateTime OrderDate { get; set; }
    public virtual IList<OrderDetail> OrderDetails { get; set; }
    [IgnoreDataMember]
    public virtual Customer Customer { get; set; }
}

public class OrderDetail : Entity
{
    public virtual string ProductName { get; set; }
    public virtual int Amount { get; set; }
    [IgnoreDataMember]
    public virtual Order Order{ get; set; }
}

如你看到的,Order and OrderDetail有对其父对象的反向引用,这会在序列化时导致循环引用。这可以通过忽略反向引用来解决IgnoreDataMemberAttribute.

我现在的假设是,每个子实例Order这是里面的Customer的列表属性Orders有对此的反向引用Customer实例。

这就是我重建循环树的方法:

public static class SerializationExtensions
{
    public static void UpdateChildReferences(this object input)
    {
        var hashDictionary = new Dictionary<int, object>();
        hashDictionary.Add(input.GetHashCode(), input);

        var props = input.GetType().GetProperties();
        foreach (var propertyInfo in props)
        {
            if (propertyInfo.PropertyType.GetInterfaces()
                .Any(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IEnumerable<>)))
            {

                var instanceTypesInList = propertyInfo.PropertyType.GetGenericArguments();
                if(instanceTypesInList.Length != 1)
                    continue;

                if (instanceTypesInList[0].IsSubclassOf(typeof(Entity)))
                {
                    var list = (IList)propertyInfo.GetValue(input, null);
                    foreach (object t in list)
                    {
                        UpdateReferenceToParent(input, t);
                        UpdateChildReferences(t);
                    }
                }
            }
        }
    }

    private static void UpdateReferenceToParent(object parent, object item)
    {
        var props = item.GetType().GetProperties();
        var result = props.FirstOrDefault(x => x.PropertyType == parent.GetType());

        if (result != null)
            result.SetValue(item, parent, null);
    }
}

此代码不适用于1->1目前实体引用(还不需要),但我认为它可以很容易地扩展。

现在,我可以在客户端拥有 POCO 类模型,添加/更新/删除子对象并将整个树发送回服务器。Nhibernate足够聪明来确定哪个实体是新的/更新的/删除的。它还只更新更改的实体和更改的属性!如果删除订单,它还会删除所有订单详细信息。

为了完整性,这就是流畅的 nhibernate 映射:

public class CustomerMap : ClassMap<Customer>
{
    public CustomerMap()
    {
        Schema("YOURSCHEMA");
        Table("CUSTOMER");
        Id(x => x.Id, "ID").GeneratedBy.Assigned();
        Map(x => x.Name, "NAM");
        Map(x => x.City, "CITY");
        HasMany(x => x.Orders)
            .KeyColumn("CUSTOMER_ID")
            .Not.LazyLoad()
            .Inverse()
            .Cascade.AllDeleteOrphan();


        DynamicUpdate();
    }
}

public class OrderMap : ClassMap<Order>
{
    public OrderMap()
    {
        Schema("YOURSCHEMA");
        Table("CUSTOMER_ORDER");
        Id(x => x.Id, "ID").GeneratedBy.Assigned();
        Map(x => x.OrderDate, "ORDER_DATE");
        HasMany(x => x.OrderDetails)
            .KeyColumn("ORDER_ID")
            .Not.LazyLoad()
            .Inverse()
            .Cascade.AllDeleteOrphan();

        References<Customer>(x => x.Customer, "CUSTOMER_ID");
        DynamicUpdate();
    }
}

public class OrderDetailMap : ClassMap<OrderDetail>
{
    public OrderDetailMap()
    {
        Schema("YOURSCHEMA");
        Table("ORDER_DETAIL");
        Id(x => x.Id, "ID").GeneratedBy.Assigned();
        Map(x => x.ProductName, "PRODUCT_NAME");
        Map(x => x.Amount, "AMOUNT");

        References<Order>(x => x.Order, "ORDER_ID");
        DynamicUpdate();
    }
}

DynamicUpdate()用于让nhibernate只更新改变的属性。 您现在只需要使用ISession.Merge(customer)功能可以正确保存所有内容。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ServiceStack.Text序列化循环引用 的相关文章

  • WPF 中的屏幕分辨率问题?

    我将在 WPF 中使用以下代码检测分辨率 double height System Windows SystemParameters PrimaryScreenHeight double width System Windows Syste
  • 如何尝试/捕获所有异常

    我正在完成由其他人启动的 UWP 应用程序 该应用程序经常崩溃 我总是陷入困境应用程序 at if global System Diagnostics Debugger IsAttached global System Diagnostic
  • 为什么大多数平台上没有“aligned_realloc”?

    MSVC有自己的非标准函数 aligned malloc aligned realloc and aligned free C 17和C11引入了 std aligned alloc 其结果可以是de分配有free or realloc B
  • (const T v) 在 C 中从来都不是必需的,对吗?

    例如 void func const int i 在这里 const是不必要的 因为所有参数都是按值传递的 包括指针 真的吗 C 中的所有参数确实都是按值传递 这意味着无论您是否包含该参数 实际参数都不会改变const or not 然而
  • 将字符串转换为正确的 URI 格式?

    有没有简单的方法可以将电子邮件地址字符串转换为正确的 URI 格式 Input http mywebsite com validate email 3DE4ED727750215D957F8A1E4B117C38E7250C33 email
  • 如何生成 appsettings..json 文件?

    我有一个 ASP NET Core 2 WebAPI 它将部署在以下环境中 INT QA STAGE 生产环境 基于上述 我需要有appsettings
  • 为什么 clang 使用 -O0 生成低效的 asm(对于这个简单的浮点和)?

    我正在 llvm clang Apple LLVM 版本 8 0 0 clang 800 0 42 1 上反汇编此代码 int main float a 0 151234 float b 0 2 float c a b printf f c
  • C++ 插件的“最适合”动态类型匹配

    我有一个几乎所有东西都是插件的架构 该架构以图形用户界面为基础 其中每个插件都由一个 表面 即用户可以通过其与插件交互的 UI 控件 表示 这些表面也是插件 每当添加新插件时 瘦主机都会自动确定哪个可用表面与其最匹配的 UI 如何在 C 中
  • 使用 WF 的多线程应用程序的错误处理模式?

    我正在写一个又长又详细的问题 但只是放弃了它 转而选择一个更简单的问题 但我在这里找不到答案 应用程序简要说明 我有一个 WPF 应用程序 它生成多个线程 每个线程执行自己的 WF 处理线程和 WF 中的错误 允许用户从 GUI 端进行交互
  • 从 R 到 C 处理列表并访问它

    我想使用从 R 获得的 C 列表 我意识到这个问题与此非常相似 使用 call 在 R 和 C 之间传递数据帧 https stackoverflow com questions 6658168 passing a data frame f
  • 为什么要在 C++ 中使用 typedef?

    可以说我有 set
  • DataTable:通过 LINQ 或 LAMBDA 进行动态 Group By 表达式

    我有一个数据表 我想在其中对未指定数量的字段进行分组 发生这种情况的原因是用户可以选择他想要分组的字段 所以 实际上 我将选择推入列表中 在这个选择上 我必须对我的数据表进行分组 想象一下这段代码 VB 或 C 都一样 public voi
  • 初始化 LPCTSTR /LPCWSTR [重复]

    这个问题在这里已经有答案了 我很难理解并使其正常工作 基本上归结为我无法成功初始化这种类型的变量 它需要有说的内容7 2E25DC9D 0 USB003 有人可以解释 展示这种类型的正确初始化和类似的值吗 我已查看此站点上的所有帮助 将项目
  • 如何引用解决方案之外的项目?

    我有一个 Visual Studio C 解决方案 其中包含一些项目 其中一个项目需要引用另一个不属于解决方案的项目 一开始我引用了dll
  • 为什么 Linux 对目录使用 getdents() 而不是 read()?

    我浏览 K R C 时注意到 为了读取目录中的条目 他们使用了 while read dp gt fd char dirbuf sizeof dirbuf sizeof dirbuf code Where dirbuf是系统特定的目录结构
  • C语言声明数组没有初始大小

    编写一个程序来操纵温度详细信息 如下所示 输入要计算的天数 主功能 输入摄氏度温度 输入功能 将温度从摄氏度转换为华氏度 独立功能 查找华氏度的平均温度 我怎样才能在没有数组初始大小的情况下制作这个程序 include
  • 受限 AppDomain 中的代码访问安全异常

    Goal 我需要在权限非常有限的 AppDomain 中运行一些代码 它不应该访问任何花哨或不安全的内容 except对于我在其他地方定义的一些辅助方法 我做了什么 我正在创建一个具有所需基本权限的沙箱 AppDomain 并创建一个运行代
  • 在 Xamarin 中获取 OutOfMemoryException

    java lang OutOfMemoryError 考虑增加 JavaMaximumHeapSize Java 执行时内存不足 java exe 我的 Visualstudio Xamarin 项目出现内存不足异常 请帮助我如何解决此问题
  • 带有私有设置器的 EFCore Base 实体模型属性 - 迁移奇怪的行为

    实体模型继承的类内的私有设置器似乎会导致 EFCore 迁移出现奇怪的问题 考虑以下示例 其中有多个类 Bar and Baz 继承自Foo 跑步时Add Migration多次命令 添加 删除private修饰符 生成的模式在多个方面都是
  • C#中为线程指定特殊的cpu

    我有 2 个线程 我想告诉其中一个在第一个 cpu 上运行 第二个在第二个 cpu 上运行 例如在具有两个 cpu 的机器中 我怎样才能做到这一点 这是我的代码 UCI UCIMain new UCI Thread UCIThread ne

随机推荐

  • 汇总不同聚合级别的数据 - R 和 tidyverse

    我正在创建一堆基本状态报告 我发现乏味的一件事是向我的所有表添加总行 我目前正在使用 Tidyverse 方法 这是我当前代码的示例 我正在寻找的是默认包含几个不同级别的选项 load into RStudio viewer not req
  • 改造以解析具有不定数量的对象名称的 json

    我正在使用 Retrofit 来处理 REST API 调用 我有一个返回以下 json 的 REST API MyObject 43508 field1 4339 field2 val field3 15 field4 586 78 10
  • Ruby XML 到 JSON 转换器?

    Ruby 中有一个库可以将 XML 转换为 JSON 吗 一个简单的技巧 首先你需要gem install json 那么当使用 Rails 时你可以这样做 require json require active support core
  • 重载强制转换运算符时出现歧义

    考虑下面的示例代码 include
  • Heartbleed bug 是 C 语言中经典缓冲区溢出漏洞的表现吗?

    在我们关于安全性的第一堂 CS 讲座中 我们了解了 C 的问题 即不检查所谓的缓冲区长度 以及利用此漏洞的不同方式的一些示例 在这种情况下 看起来这是一个恶意读取操作的情况 应用程序只是读出了多少字节的内存 我断言 Heartbleed b
  • Objective-C 依赖项的弃用警告

    使 Swift var 向后兼容 Objective C 我有一个 Objective C 类 已转换为 Swift 我所有的测试都通过了 但我想通过添加一个弃用警告来更新以通知用户将下游依赖项更新到 Swift 版本的 var 来进一步优
  • 为什么更好的隔离级别意味着 SQL Server 更好的性能

    在测量查询性能时 我发现隔离级别和运行时间之间存在依赖关系 这让我感到惊讶 READUNCOMMITTED 409024 READCOMMITTED 368021 REPEATABLEREAD 358019 SERIALIZABLE 348
  • 如何修改移动设备和选项卡的引导轮播

    我正在使用引导滑块 在桌面上 它有三张幻灯片 每张幻灯片有 4 个图块 在选项卡上 它们必须是 4 张幻灯片 每张幻灯片 3 个图块 在移动设备上 需要有 12 张不同的幻灯片 我正在考虑实现这一点的最有效和最优化的方法 Option 1
  • Hibernate3 与 Oracle 12c

    我们正在将 oracle 从 11g 升级到 12c 我的应用程序正在使用hibernate3 jar这是 3 6 8 最终版本 与 11g 配合使用效果很好Oracle10gDialect但是当我连接到 12c 数据库时出现以下错误 我还
  • 使用 ezplot 在 MATLAB 中的同一个图形上绘制两个函数

    我想使用 ezplot 在 MATLAB 中绘制以下三个函数 但我希望这些函数位于同一张图上 以便轻松解释差异 这可能吗 如果是这样怎么办 这三个功能是 x 3 x 5 x 7 thanks 神秘的xhobo 只需使用hold on将它们连
  • 什么是缩放图像以及如何在网页中提供缩放图像?

    当我在 google PageSpeed 中运行测试页面时 我发现了一些警告 例如提供缩放图像 http man vimal net78 net introduction intro action main THe results were
  • IEnumerable 是如何逆变的?

    这个帖子 http blogs msdn com b brada archive 2005 01 18 355755 aspx https web archive org web 20140417104304 http blogs msdn
  • 如何为 google api php 客户端库设置超时

    我正在使用谷歌的PHP 客户端库 https github com google google api php client构建一个应用程序 有时 Google 需要长达 100 秒的时间来响应 API 请求 我想将套接字超时限制为 30
  • Keras 中的 dropout 行为,rate=1(丢弃所有输入单元)不符合预期

    input0 keras layers Input 32 32 3 name Input0 flatten keras layers Flatten name Flatten input0 relu1 keras layers Dense
  • 如何为 WPF 应用程序创建 chm 帮助文件?

    对于 WPF UI 应用程序 需要创建 CHM 帮助文件 如何创建 chm 帮助文件 首先在ms word中创建文档并将其转换为chm帮助文件 或者任何其他方法 请帮忙 Thanks Ramm I used Sandcastle 帮助文件生
  • Database.BeginTransaction 与 Transactions.TransactionScope [重复]

    这个问题在这里已经有答案了 有什么区别System Transactions TransactionScope和 EF6 的Database BeginTransaction 有人可以举一个小例子 或者只是解释一下当有明显差异时应该使用哪一
  • 获取列位置

    在 Cassandra DB 中 使用有序列族 我知道你能得到切片 但你能得到位置吗 例如 在此数据模型中 我保存如下分数 Scores 1000 bob lucas 900 tim 800 mario 知道用户的分数为 900 并且他的昵
  • 传递Physics2DShapeQueryParameters 层进行检查

    我目前正在为我的 2D 自上而下游戏开发一个构建系统 最后一步是检查是否有任何物体 例如树或玩家 阻碍了物品的放置 经过一些研究后 我发现使用Physics2DShapeQueryParameters 是正确的方法 我唯一的问题是我不知道如
  • 仅克隆雪花元数据

    我想克隆 Snowflake 数据库的外壳 仅元数据 无数据 这可能吗 我检查了文档并没有找到解决方案 如果您只是想获取现有数据库的空壳 则可以克隆整个数据库 然后编写脚本截断数据库中存在的所有表 克隆不会添加任何数据 并且克隆上的截断速度
  • ServiceStack.Text序列化循环引用

    我需要像这样序列化对象图 public class A public B Link1 get set public class B public A Link2 get set 这样json只得到两个实例 但又被正确反序列化了 例如 使用元