MongoDB .NET 驱动程序未反序列化集合
MongoDB .NET Driver not deserializing for collection
我在从 MongoDB 反序列化集合时遇到问题。对于单个对象似乎没问题,但对于对象集合却失败了。该集合是 Mongo 中带有坐标的 GeoJSON 对象。这似乎是问题所在。也许我在我的 C# class 中没有代表那个权利。虽然它似乎对单个对象工作正常。
我根据这个 post 创建了一个通用集合存储库:Generic Mongo Repository pattern implemented in .NET Core
鉴于我的 class:
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; }
}
}
和 Mongo数据库集合:
和 small 文件本身的片段(我根据 Importing a Shapefile into MongoDB using GeoJSON 从 Shapefile 转换而来):
[
{ "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: An error occurred while deserializing the Geometry property of class VisualStatsPoCAPI.Repositories.Models.Mongo.GardaSubdistrictBoundaryMongo: An error occurred while deserializing the Coordinates property of class VisualStatsPoCAPI.Repositories.Models.Mongo.Geometry: Cannot deserialize a 'Double' from 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());
}
这与我如何表示几何有关,但我不确定。我有点困惑。有人可以帮忙吗?
更新(2020 年 3 月 25 日):
有人建议我使用 GeoJsonPolygon。我试过像下面这样使用它:
public GeoJsonPolygon<GeoJson2DCoordinates> Geometry { get; set; }
同样,这对单个文档也适用。当我尝试将其用于整个系列时,我得到:
System.FormatException: An error occurred while deserializing the Geometry property of class VisualStatsPoCAPI.Repositories.Models.Mongo.GardaSubdistrictBoundaryMongo: Invalid GeoJson type: 'MultiPolygon'. Expected: 'Polygon'.
当我切换到使用 GeoJsonMultiPolygon(如编译器建议的那样)时,我得到:
System.FormatException: An error occurred while deserializing the Geometry property of class VisualStatsPoCAPI.Repositories.Models.Mongo.GardaSubdistrictBoundaryMongo: Invalid GeoJson type: 'Polygon'. Expected: 'MultiPolygon'.
从提供的屏幕截图和模型中看不清楚,但粘贴您遇到的错误后就清楚了。
您的 collection 似乎同时包含 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>
). Both classes derive from GeoJsonGeometry<GeoJson2DCoordinates>
. Furthermore you can use GeoJson2DCoordinates 代表您的 two-element 双精度数组。
驱动程序将处理其余部分 - 您可以将基本抽象类型指定为 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; }
}
我在从 MongoDB 反序列化集合时遇到问题。对于单个对象似乎没问题,但对于对象集合却失败了。该集合是 Mongo 中带有坐标的 GeoJSON 对象。这似乎是问题所在。也许我在我的 C# class 中没有代表那个权利。虽然它似乎对单个对象工作正常。
我根据这个 post 创建了一个通用集合存储库:Generic Mongo Repository pattern implemented in .NET Core
鉴于我的 class:
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; }
}
}
和 Mongo数据库集合:
和 small 文件本身的片段(我根据 Importing a Shapefile into MongoDB using GeoJSON 从 Shapefile 转换而来):
[
{ "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: An error occurred while deserializing the Geometry property of class VisualStatsPoCAPI.Repositories.Models.Mongo.GardaSubdistrictBoundaryMongo: An error occurred while deserializing the Coordinates property of class VisualStatsPoCAPI.Repositories.Models.Mongo.Geometry: Cannot deserialize a 'Double' from 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());
}
这与我如何表示几何有关,但我不确定。我有点困惑。有人可以帮忙吗?
更新(2020 年 3 月 25 日): 有人建议我使用 GeoJsonPolygon。我试过像下面这样使用它:
public GeoJsonPolygon<GeoJson2DCoordinates> Geometry { get; set; }
同样,这对单个文档也适用。当我尝试将其用于整个系列时,我得到:
System.FormatException: An error occurred while deserializing the Geometry property of class VisualStatsPoCAPI.Repositories.Models.Mongo.GardaSubdistrictBoundaryMongo: Invalid GeoJson type: 'MultiPolygon'. Expected: 'Polygon'.
当我切换到使用 GeoJsonMultiPolygon(如编译器建议的那样)时,我得到:
System.FormatException: An error occurred while deserializing the Geometry property of class VisualStatsPoCAPI.Repositories.Models.Mongo.GardaSubdistrictBoundaryMongo: Invalid GeoJson type: 'Polygon'. Expected: 'MultiPolygon'.
从提供的屏幕截图和模型中看不清楚,但粘贴您遇到的错误后就清楚了。
您的 collection 似乎同时包含 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>
). Both classes derive from GeoJsonGeometry<GeoJson2DCoordinates>
. Furthermore you can use GeoJson2DCoordinates 代表您的 two-element 双精度数组。
驱动程序将处理其余部分 - 您可以将基本抽象类型指定为 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; }
}