[Fork] [Fork] https://stackoverflow.com/questions/75159862/performance-issue-with-deserlizing-large-json-file-into-objects-and-add-them-to

CSharp · Console

/Program.cs

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.ComponentModel.DataAnnotations;
using System.Threading.Tasks;

using System.Text.Json;
using System.Text.Json.Serialization;

using NUnit.Framework; // Throws NUnit.Framework.AssertionException



#nullable enable

//https://stackoverflow.com/questions/75159862/performance-issue-with-deserlizing-large-json-file-into-objects-and-add-them-to

	public class Country
    {
        [Key]
        //[DatabaseGenerated(DatabaseGeneratedOption.None)]
        public int Id { get; set; }
        public string Name { get; set; }
        public string ISO2 { get; set; }
        public string ISO3 { get; set; }

        public ICollection<City> Cities { get; set; }
    }

	public class City
	{
		[Key]
		//[DatabaseGenerated(DatabaseGeneratedOption.None)]
		public int Id { get; set; }
		public string Name { get; set; }
		public int CountryId { get; set; }
        public Country Country { get; set; }		
	}

    class TestClass
    {
		public static async Task Test()
		{
			var fileName = "Question75159862.json";
			
			await File.WriteAllTextAsync(fileName, GetJson());

			var countries = new List<Country>();
			
			await using var stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize: 4096, useAsync: true);
			var options = new JsonSerializerOptions
			{
				PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
				//PropertyNameCaseInsensitive is required to deserialize "isO2" and "isO3" correctly
				PropertyNameCaseInsensitive = true,
			};
			await foreach (var country in JsonSerializer.DeserializeAsyncEnumerable<Country>(stream, options))
			{
				if (country == null)
					continue;
				if (country.Cities != null)
					foreach (var city in country.Cities)
					{
						// Do you need another instance of City?  If so you may clone the current one as follows:
						var clone = JsonSerializer.Deserialize<City>(JsonSerializer.SerializeToUtf8Bytes(city));

						city.CountryId = country.Id;
						//context.Cities.Add(cities);
						//context.Entry(cities).State = Microsoft.EntityFrameworkCore.EntityState.Detached;
					}
				countries.Add(country);
			}

			Console.WriteLine("Deserialized and re-serialized {0}:", countries);
			var writeOptions = new JsonSerializerOptions
			{
				PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
				PropertyNameCaseInsensitive = true,
				WriteIndented = true,
			};
			Console.WriteLine(JsonSerializer.Serialize(countries, writeOptions));
		}
		
		static string GetJson() =>
"""
[
   {
      "id":1,
      "name":"Afghanistan",
      "iso3":"AFG",
      "iso2":"AF",
      "cities":[
         {
            "id":141,
            "name":"‘Alāqahdārī Dīshū"
         },
         {
            "id":53,
            "name":"Aībak"
         },
         {
            "id":50,
            "name":"Andkhoy"
         },
         {
            "id":136,
            "name":"Āqchah"
         },
         {
            "id":137,
            "name":"Ārt Khwājah"
         },
         {
            "id":51,
            "name":"Asadabad"
         },
         {
            "id":52,
            "name":"Ashkāsham"
         },
         {
            "id":138,
            "name":"Āsmār"
         },
         {
            "id":54,
            "name":"Baghlān"
         },
         {
            "id":55,
            "name":"Balkh"
         }
      ]
   }
]
""";
	}

	public class Program
	{
		public static async Task Main(string[] args)
		{
			Console.WriteLine("Environment version: {0} ({1}), {2}", System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription , Environment.Version, Environment.OSVersion);
			Console.WriteLine("{0} version: {1}", typeof(JsonSerializer).Namespace, typeof(JsonSerializer).Assembly.FullName);
			Console.WriteLine();

			try
			{
				await TestClass.Test();
			}
			catch (Exception ex)
			{
				Console.WriteLine("Failed with unhandled exception: ");
				Console.WriteLine(ex);
				throw;
			}
		}
	}
;