Save and Undo ScriptableObject from Editor.OnSceneGUI()

My goal is to update a 2D array from an editor script and being able to save it and undo the changes. I use a ScriptableObject and an intermediate object to encapsulate the array:

// Array wrapper
[Serializable]
public class CityMapArray<T> : IIndexed<T>
{
    [SerializeField] private T[,] _array;

    public CityMapArray()
    {
        _array = new T[1, 1];
    }

    public CityMapArray(int width, int height)
    {
        _array = new T[width, height];
    }

    public CityMapArray(T[,] array)
    {
        UpdateMap(array);
    }

    public void UpdateMap(T[,] array)
    {
        CopyArray(_array, out _backup);
        _array = new T[array.GetLength(0), array.GetLength(1)];
        if (array.Rank != 2)
            throw new ArgumentException($"{nameof(array)} must be a 2D array.");

        for (var x = 0; x < array.GetLength(0); x++)
        {
            for (var z = 0; z < array.GetLength(1); z++)
            {
                this[x, z] = array[x, z];
            }
        }
    }

    public T this[int x, int z]
    {
        get
        {
            return _array[x, z];
        }
        set
        {
            _array[x, z] = value;
        }
    }

    public int GetLength(int dimension)
    {
        return _array.GetLength(dimension);
    }
}
[Serializable]
public class CityMapData : ScriptableObject
{
    // ...
    // I'm using a complex object instead of int?
    [SerializeField] private CityMapArray<int?> _cityMap;

    public CityMapArray<int?> CityMap => _cityMap;
}

And I’m using it this way:

[ExecuteInEditMode]
public class City : MonoBehaviour
{
    [SerializeField] private CityMapData _cityMapData;

    public CityMapData CityMapData => _cityMapData;
    public CityMapArray<int?> CityMap => CityMapData == null ? null : CityMapData.CityMap;

    // ...

    public void ChangeMapSize(/* ... */)
    {
        // ...
        var newMap = new int?[newWidth, newHeight];
        CityMap.UpdateMap(newMap);

        // ...
    }
}

This is the custom editor:

[CustomEditor(typeof(City)), CanEditMultipleObjects]
public class CityEditor : Editor
{
    // ...

    public override void OnInspectorGUI()
    {
        var myTarget = (City)target;

        if (GUILayout.Button("Save map"))
        {
            // doesn't work
            EditorUtility.SetDirty(myTarget.CityMapData);
            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();
        }
    }

    public void OnSceneGUI()
    {
        var t = target as City;
        if (Event.current.type == EventType.MouseUp && Event.current.button == 0)
        {
            EditorUtility.SetDirty(myTarget.CityMapData);
            // throws an error
            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();
        }

        EditorGUI.BeginChangeCheck();

        // changing the array in some ways 
        if (EditorGUI.EndChangeCheck())
        {
           
            if (changed)
            {
                // registers simple properties of City, but the CityMapData stays the same
                Undo.RegisterCompleteObjectUndo(new UnityEngine.Object[] { t, t.CityMapData }, "Change Map size");
                t.ChangeMapSize(/* ... */);
            }
        }
    }
}

As you can see when I change the data, a new array is being created.

Not a single save method works: when I save the object from OnSceneGUI() it throws an error, from OnInspectorGUI() nothing happens (I reopen the editor and nothing has been saved). The Undo operation works only for simple properties of City class, but not for the CityMapData.

How should it be done here?