Cinchoo ETL——将JSON反序列化为没有类型信息的多态类

目录

1、简介

2. 要求

3. 如何使用

3.1 样本数据

3.2 反序列化(方法一)

3.3 反序列化(方法二)

3.4 反序列化(方法四)


1、简介

ChoETL是一个用于.NET的开源ETL(提取、转换和加载)框架。它是一个基于代码的库,用于在.NET环境中从多个来源提取数据、转换并加载到您自己的数据仓库中。您可以立即在数据仓库中获取数据。

本技巧介绍使用Cinchoo ETL框架从JSON格式生成CSV文件。使用非常简单,几行代码就可以完成转换。您可以转换大文件,因为转换过程是基于流的,速度非常快且内存占用少。

2. 要求

该框架库是使用.NET 4.5 / .NET Core FrameworksC#编写的。

3. 如何使用

3.1 样本数据

让我们从一个简单的示例开始,该示例转换以下JSON输入文件,其中包含以JSON表示的Gallery ItemGallery Album对象。

清单 3.1.1 示例JSON数据输入文件(Img.json)

[
  {
    "id": "OUHDm",
    "title": "My most recent drawing. Spent over 100 hours.",
    "is_album": false
  },
  {
    "id": "lDRB2",
    "title": "Imgur Office",
    "is_album": true,
    "images_count": 3,
    "images": [
      {
        "id": "24nLu",
        "link": "http://i.imgur.com/24nLu.jpg"
      },
      {
        "id": "Ziz25",
        "link": "http://i.imgur.com/Ziz25.jpg"
      },
      {
        "id": "9tzW6",
        "link": "http://i.imgur.com/9tzW6.jpg"
      }
    ]
  }
]

您可以看到没有可用于自动反序列化的类型信息。'is_album'属性用于将JSON反序列化为Gallery Item(如果'is_album'false)或Gallery Album对象(如果 'is_album'true)。

.NET Framework

Install-Package ChoETL.JSON

.NET Core

Install-Package ChoETL.JSON.NETStandard

现在将ChoETL命名空间添加到程序中。

using ChoETL;

3.2 反序列化(方法一)

以下是将JSON成功反序列化为多态类的步骤。在这种方法中,您可以完全控制扫描节点并根据特定节点值选择适当的多态类型进行反序列化。 

首先,定义类以匹配JSON,如下所示。

清单 3.2.1 POCO类树

public interface IGalleryItem
{
}

public class GalleryItem : IGalleryItem
{
    public string id { get; set; }
    public string title { get; set; }
    public bool is_album { get; set; }
}

public class GalleryAlbum : GalleryItem
{
    public int images_count { get; set; }
    public List<GalleryImage> images { get; set; }
}

public class GalleryImage
{
    public string id { get; set; }
    public string link { get; set; }
}

其中定义了两个具体的类,GalleryItemGalleryAlbumIGalleryItem接口派生来保存JSON内容。

接下来使用Cinchoo ETL,对JSON进行反序列化,如下所示。

清单 3.2.2 反序列化

private static void QuickConversion()
{
    using (var r = new ChoJSONReader<IGalleryItem>("img.json")
        .Configure(c => c.SupportsMultiRecordTypes = true)
        .Configure(c => c.RecordTypeSelector = o =>
        {
            dynamic kvp = o as dynamic;
            dynamic jObject = kvp.Item2 as dynamic;
            switch ((bool)jObject.is_album)
            {
                case true:
                    return typeof(GalleryAlbum);
                default:
                    return typeof(GalleryItem);
            }
        })
        )
    {
        foreach (var rec in r)
            Console.Write(rec.Dump());
    }
}

创建用于读取img.json文件的ChoJSONReader对象实例。使用以下配置设置成功解析 JSON

  • RecordTypeSelector——根据is_album属性值选择要反序列化的记录类型的功能。这个回调是带Tuple<int, object>参数传递的,其中item1是节点索引,item2JObject。从item2,您可以检查is_album属性值以确定要序列化的类类型。
  • SupportsMultiRecordTypes——true,告诉解析器处理多态反序列化。

Fiddle示例https ://dotnetfiddle.net/IRZOu3

3.3 反序列化(方法二)

在这种方法中,基于鉴别器(即is_album)字段选择要反序列化的子类型的方式有点简化。

首先,定义类以匹配JSON,如下所示。

清单 3.3.1 POCO类树

public interface IGalleryItem
{
}

public class GalleryItem : IGalleryItem
{
    public string id { get; set; }
    public string title { get; set; }
    public bool is_album { get; set; }
}

public class GalleryAlbum : GalleryItem
{
    public int images_count { get; set; }
    public List<GalleryImage> images { get; set; }
}

public class GalleryImage
{
    public string id { get; set; }
    public string link { get; set; }
}

其中定义了两个具体的类,GalleryItemGalleryAlbumIGalleryItem接口派生来保存JSON内容。

接下来使用Cinchoo ETL,对JSON进行反序列化,如下所示。

清单 3.3.2 反序列化

private static void QuickConversion()
{
    using (var r = new ChoJSONReader<IGalleryItem>("img.json")
        .Configure(c => c.KnownTypeDiscriminator = "is_album")
        .Configure(c => c.RecordTypeSelector = o =>
        {
            var isAlbum = o.CastTo<bool>();
            return !isAlbum ? typeof(GalleryAlbum) : typeof(GalleryItem);
        })
        .Configure(c => c.SupportsMultiRecordTypes = true)
        )
    {
        r.Print();
    }
}

创建用于读取img.json文件的ChoJSONReader对象实例。使用以下配置设置成功解析JSON

  • KnownTypeDiscriminator——指定鉴别器字段(is_album
  • RecordTypeSelector——根据is_album属性值选择要反序列化的记录类型的功能。这个回调是带Tuple<int, object>参数传递的,其中item1是节点索引,item2是鉴别器值。从item2,您可以检查is_album属性值以确定要序列化的类类型。
  • SupportsMultiRecordTypes——true,告诉解析器处理多态反序列化。

Fiddle示例https ://dotnetfiddle.net/xGMMIt

3.4 反序列化(方法四)

在这种方法中,通过将类属性定义到基本抽象/接口类来简化选择多态子类型的方法。

首先,定义类以匹配JSON,如下所示。

清单 3.4.1 POCO类树

[ChoKnownTypeDiscriminator("is_album")]
[ChoKnownType(typeof(GalleryAlbum), "true")]
[ChoKnownType(typeof(GalleryItem), "false")]
public interface IGalleryItem
{
}

public class GalleryItem : IGalleryItem
{
    public string id { get; set; }
    public string title { get; set; }
    public bool is_album { get; set; }
}

public class GalleryAlbum : GalleryItem
{
    public int images_count { get; set; }
    public List<GalleryImage> images { get; set; }
}

public class GalleryImage
{
    public string id { get; set; }
    public string link { get; set; }
}

其中定义了两个具体的类,GalleryItemGalleryAlbumIGalleryItem接口派生来保存JSON内容。

ChoKnownTypeDiscriminatorAttribute定义鉴别器字段。用ChoKnownTypeAttribute定义匹配鉴别器的多态子类型。

接下来使用Cinchoo ETL,对JSON进行反序列化,如下所示。

清单 3.4.2 反序列化

private static void QuickConversion()
{
    using (var r = new ChoJSONReader<IGalleryItem>("img.json")
        .Configure(c => c.SupportsMultiRecordTypes = true)
        )
    {
        r.Print();
    }
}

创建用于读取img.json文件的ChoJSONReader对象实例。使用以下配置设置成功解析 JSON

  • SupportsMultiRecordTypes——true,告诉解析器处理多态反序列化。

Fiddle样本https ://dotnetfiddle.net/mCl4NJ

JSONCSV请参考其他类似文章:

https://www.codeproject.com/Tips/5314341/Cinchoo-ETL-Deserializing-JSON-to-Polymorphic-Clas

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值