【问题标题】:using MongoDB C# Driver order Document Fields with inherited type objects使用带有继承类型对象的 MongoDB C# 驱动程序订购文档字段
【发布时间】:2016-11-30 11:22:26
【问题描述】:

我的 C# 中有以下两个类,我在 Mongo Collection 中使用 BsonElement 进行属性顺序。但是 Car collection 没有实现这个顺序。

这里的想法是在BaseEntity 类中拥有这个公共字段并在几乎所有类上继承它

public class Car: BaseEntity{
   [BsonElement(Order = 1)]
   public string Color{ get; set; }
   [BsonElement(Order = 2)]
   public long Price{ get; set; }
}

public class BaseEntity{
   [BsonElement(Order = 99)]
   public DateTime DateAdded{ get; set; }
   [BsonElement(Order = 100)]
   public bool IsActive{ get; set; }
}

Mongo 中的汽车收集结果如下。尽管我有 BsonElement(Order=xx)

,但基类属性在文档和子类中排在首位
{
   "_id" :ObjectId(fsdfsdfsdfsdfs),
   "DateAdded": ISO("SomeDate"),
   "IsActive" : true,
   "Color" : "Red",
   "Price" : NumberLong(23564)
}

我希望它看起来像

{
   "_id" :ObjectId(fsdfsdfsdfsdfs),
   "Color" : "Red",
   "Price" : NumberLong(23564)
   "DateAdded": ISO("SomeDate"),
   "IsActive" : true
}

司机详情

  <package id="mongocsharpdriver" version="2.2.4" targetFramework="net461" />
  <package id="MongoDB.Bson" version="2.2.4" targetFramework="net461" />
  <package id="MongoDB.Driver" version="2.2.4" targetFramework="net461" />
  <package id="MongoDB.Driver.Core" version="2.2.4" targetFramework="net461" />

【问题讨论】:

  • 这个顺序是有道理的,因为你正在实现继承......这就是为什么基类首先订购......覆盖它的唯一方法应该是实现一个覆盖 BsonElement 的类......但是,既然你的类这么小,为什么要继承,或者你只是为了练习目的?
  • 这是一个示例代码,我在 Base 类中有大约 8 个属性,需要在所有 Mongo 集合(类)中继承,是的,它也用于练习。如果我有 8 个 Collection 类,我不想在 8 个子类中重复这个基类属性
  • 仅用于测试:如果您从基类中删除 Order?
  • 有无订单没有区别
  • 这很奇怪....根据文档Any fields or properties that do not have an explicit Order will occur after those that do have an Order.

标签: c# asp.net-mvc mongodb c#-4.0 bson


【解决方案1】:

也许它不会落入预期的答案,但类内部使用的属性在那里得到尊重,这意味着序列化程序首先使用它的基元素构建最终类,然后是来自具体对象的元素。

为了测试它,我创建了 class bus:car

public class Bus:Car{
[BsonElement(Order = 1)]
   public string BusColor{ get; set; }
   [BsonElement(Order = 2)]
   public long BusPrice{ get; set; }
}

并且输出刚刚确认:

{
    "_id" : ObjectId("5799eb7c1751a60613b36cbc"),
    "DateAdded" : ISODate("2016-07-28T11:24:44.222Z"),
    "IsActive" : true,
    "Color" : "Black-White",
    "Price" : NumberLong(923),
    "BusColor" : "Blue",
    "BusPrice" : NumberLong(12345)
}

你打算用这种排序解决什么样的问题?

欢迎任何 cmets!

===========

编辑

在bson驱动源码中发现

 private void OrderMembers()
    {
        // only auto map properties declared in this class (and not in base classes)
        var hasOrderedElements = false;
        var hasUnorderedElements = false;
        foreach (var memberMap in _declaredMemberMaps)
        {
            if (memberMap.Order != int.MaxValue)
            {
                hasOrderedElements |= true;
            }
            else
            {
                hasUnorderedElements |= true;
            }
        }

        if (hasOrderedElements)
        {
            if (hasUnorderedElements)
            {
                // split out the unordered elements and add them back at the end (because Sort is unstable, see online help)
                var unorderedElements = new List<BsonMemberMap>(_declaredMemberMaps.Where(pm => pm.Order == int.MaxValue));
                _declaredMemberMaps.RemoveAll(m => m.Order == int.MaxValue);
                _declaredMemberMaps.Sort((x, y) => x.Order.CompareTo(y.Order));
                _declaredMemberMaps.AddRange(unorderedElements);
            }
            else
            {
                _declaredMemberMaps.Sort((x, y) => x.Order.CompareTo(y.Order));
            }
        }
    }

【讨论】:

  • 正如我在问题中解释的那样,我希望基类属性位于最后。那么我该如何实现呢?
  • 嗯,它在 Mongo 查询的 JSON 文档中的显示顺序,我不希望这些字段显示在顶部,我们必须滚动每个结果以获取特定的记录详细信息
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-18
  • 2022-01-08
  • 1970-01-01
相关资源
最近更新 更多