MongoDB. NET Драйвер не десериализован для сбора - PullRequest
1 голос
/ 24 марта 2020

У меня проблема с десериализацией коллекции из MongoDB. Кажется, хорошо для одного объекта, но не для коллекции объектов. Коллекция представляет собой объект Geo JSON в Mon go с координатами. Кажется, это проблема. Возможно, я не представляю это право в моем C# классе. Хотя кажется, что он отлично работает для одного объекта.

Я создал универсальное репо c коллекции в соответствии с этим постом: Generi c Пн go Шаблон репозитория, реализованный в. NET Core

Учитывая мой класс:

using System.Collections.Generic;
using MongoDB.Driver.GeoJsonObjectModel;
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;

namespace VisualStatsPoCAPI.Repositories.Models.Mongo
{
    [BsonCollection("garda_subdistrict_boundaries")]
    public class GardaSubdistrictBoundaryMongo : Document
    {
        [BsonElement("type")]
        public string Type { get; set; }

        [BsonElement("properties")]
        public Properties Properties { get; set; }

        [BsonElement("geometry")]
        public Geometry Geometry { get; set; }
    }

    public class Properties
    {
        public string REGION { get; set; }
        public string REG_CODE { get; set; }
        public string DIVISION { get; set; }
        public string DIV_CODE { get; set; }
        public string DISTRICT { get; set; }
        public string DIST_CODE { get; set; }
        public string SUB_DIST { get; set; }
        public string SUB_IRISH { get; set; }
        public string SUB_CODE { get; set; }
        public string COUNTY_1 { get; set; }
        public string COUNTY_2 { get; set; }
        public string GEOGID { get; set; }
        public int Male2011 { get; set; }
        public int Female2011 { get; set; }
        public int Total2011 { get; set; }
        public int PPOcc2011 { get; set; }
        public int Unocc2011 { get; set; }
        public int Vacant2011 { get; set; }
        public int HS2011 { get; set; }
        public double PCVac2011 { get; set; }
        public string CREATEDBY { get; set; }
    }

    public class Geometry
    {
        [BsonElement("type")]
        public string Type { get; set; }

        [BsonElement("coordinates")]
        public IEnumerable<IEnumerable<GeoJson2DCoordinates>> Coordinates { get; set; }
    }
}

и коллекцию MongoDB:

enter image description here

и маленький фрагмент самого элемента (который я преобразовал из шейп-файла согласно Импортированию шейп-файла в MongoDB с использованием Geo JSON):

[
    { "type": "Feature", 
      "properties": { 
          "REGION": "Southern Region", 
          "REG_CODE": "03", 
          "DIVISION": "Cork West", 
          "DIV_CODE": "0319", 
          "DISTRICT": "Bandon", 
          "DIST_CODE": "4300A", 
          "SUB_DIST": "Kinsale", 
          "SUB_IRISH": "Cionn tS�ile", 
          "SUB_CODE": "4305B", 
          "COUNTY_1": "Cork", 
          "COUNTY_2": null, 
          "GEOGID": "M4305B", 
          "Male2011": 5765, 
          "Female2011": 5963, 
          "Total2011": 11728, 
          "PPOcc2011": 4054, 
          "Unocc2011": 1177, 
          "Vacant2011": 1013, 
          "HS2011": 5231, 
          "PCVac2011": 19.4, 
          "CREATEDBY": "Paul Creaner" 
       }, 
       "geometry": { 
           "type": "Polygon", 
           "coordinates": [ 
               [ 
                   [-8.665517347801826, 51.701921804534543 ], 
                   [-8.665512199746647, 51.702050730841847 ] 
               ] 
           ] 
        } 
    }
]

Я получаю ошибка:

System.FormatException: произошла ошибка при десериализации свойства Geometry класса VisualStatsPoCAPI.Repositories.Models.Mon go .GardaSubdistrictBoundaryMon go: при десериализации свойства Coordinates произошла ошибка класса VisualStatsPoCAPI.Repositories.Models.Mon go .Geometry: Невозможно десериализовать 'Double' из BsonType 'Array'.

Вызов SDK, который я использую для одного объекта:

public virtual TDocument FindOne(Expression<Func<TDocument, bool>> filterExpression)
{
    return _collection.Find(filterExpression).FirstOrDefault();
}

и для коллекция, либо:

public virtual IEnumerable<TProjected> FilterBy<TProjected>(
    Expression<Func<TDocument, bool>> filterExpression,
    Expression<Func<TDocument, TProjected>> projectionExpression)
{
    return _collection.Find(filterExpression).Project(projectionExpression).ToEnumerable();
}

или

public virtual Task<IEnumerable<TDocument>> FindAll()
{
    FilterDefinition<TDocument> filter = FilterDefinition<TDocument>.Empty;

    return Task.Run(() => _collection.Find(filter).ToList().AsEnumerable());
}

Это как-то связано с тем, как я представляю геометрию, но я не уверен. Я немного смущен. Кто-нибудь может помочь?

Обновление (25 марта 2020 г.): Было предложено использовать GeoJsonPolygon. Я попытался использовать это, как показано ниже:

public GeoJsonPolygon<GeoJson2DCoordinates> Geometry { get; set; }

Опять же, это прекрасно работает для одного документа. Когда я пытаюсь использовать это для всей коллекции, я получаю:

System.FormatException: произошла ошибка при десериализации свойства Geometry класса VisualStatsPoCAPI.Repositories.Models.Mon go .GardaSubdistrictBoundaryMon go: Недопустимый тип Geo Json: «MultiPolygon». Ожидается: 'Polygon'.

Когда я переключаюсь на использование GeoJsonMultiPolygon (как предлагает компилятор), я получаю:

System.FormatException: при десериализации произошла ошибка свойство Geometry класса VisualStatsPoCAPI.Repositories.Models.Mon go .GardaSubdistrictBoundaryMon go: недопустимый Geo Json тип: 'Многоугольник'. Ожидаемый: «MultiPolygon».

1 Ответ

0 голосов
/ 29 марта 2020

Это неясно из предоставленного снимка экрана и модели, но стало ясно, когда вы вставили ошибки, которые вы получаете.

Похоже, ваша коллекция содержит оба значения: Polygons:

{ geometry: { 'type' : 'Polygon', 'coordinates' : [[[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 0.0]]] } }

и MultiPolygons:

{ geometry: { 'type' : 'MultiPolygon', 'coordinates' : [[[[102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0]]], [[[102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0]], [[102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0]]]] } }

MongoDB. NET драйвер предоставляет классы для обоих типов многоугольников (GeoJsonPolygon<TCoordinates>, GeoJsonMultiPolygon<TCoordinates>). Оба класса происходят от GeoJsonGeometry<GeoJson2DCoordinates>. Кроме того, вы можете использовать GeoJson2DCoordinates для представления двухэлементных массивов значений типа double.

Драйвер будет обрабатывать все остальное - вы можете указать базовый абстрактный тип как Geometry, и документ будет десериализован для соответствующего типа бетона во время выполнения:

[BsonCollection("garda_subdistrict_boundaries")]
public class GardaSubdistrictBoundaryMongo : Document
{
    [BsonElement("type")]
    public string Type { get; set; }

    [BsonElement("properties")]
    public Properties Properties { get; set; }

    [BsonElement("geometry")]
    public GeoJsonGeometry<GeoJson2DCoordinates> Geometry { get; set; }
}

enter image description here

...