繁体   English   中英

Mongo C#Driver:反序列化BsonArray

[英]Mongo C#Driver:Deserialize BsonArray

我在mongodb中有一个文档,其结构类似于此:

{
    "_id":xxxxx,
    "business":[{
            "subBusiness":[{
                "subBusinessName":"Abusiness",
                "a":"aaaa"
            },{
                "subBusinessName":"Bbusiness",
                "b":"bbbbb",
                "c":"ccccc"
                }]
        }]
}

如何制作一个映射类来序列化此文档?

我也定义了一个代表尺寸的类(上面的子文档)

class STObject{
    [BsonId]
    public ObjectId id{get;set;}
    [BsonElement("business")]
    public List<Business> BusinessList{get;set;}
}
class Business  {   
    [BsonElement("subBusiness")]
    public List<SubBusiness> SubBuiness { get; set; }
}
[BsonDiscriminator(RootClass = true)]
[BsonKnownTypes(typeof(CSSubBusiness),typeof(ApproSubBusiness))]
public class SubBusiness {
    [BsonElement("subBusinessName")]
    public string SubBusinessName{get;set;}
}
public class AsubBusiness:SubBusiness{
    [BsonElement("a")]
    public string A{get;set;}   
}
public class BsubBusiness:SubBusiness{
    [BsonElement("b")]
    public string B{get;set;}
    [BsonElement("c")]
    public string C{get;set;}
}

如何在类STObject中查询元素“ b”?

为了反序列化类层次结构 ,文档应包含类型鉴别符字段,该字段指示应实例化哪种类型的子类。 默认情况下,该字段的名称为_t 但是,如果您已经拥有具有上述架构的文档,并且无法更改它,那么您应该覆盖Mongo使用的区分符约定。

看起来您可以将subBusinessName字段用作子业务类型的类型区分subBusinessName 为此,您应该从基本类型中删除此字段:

[BsonDiscriminator(RootClass = true)]
[BsonKnownTypes(typeof(AsubBusiness), typeof(BsubBusiness))] // btw check types
public class SubBusiness
{        
}

并且您应该为子类型提供鉴别符值:

[BsonDiscriminator("Abusiness")] // provide discriminator value here
public class AsubBusiness : SubBusiness
{
    [BsonElement("a")]
    public string A { get; set; }
}

[BsonDiscriminator("Bbusiness")]
public class BsubBusiness : SubBusiness
{
    [BsonElement("b")]
    public string B { get; set; }
    [BsonElement("c")]
    public string C { get; set; }
}

最后一步-创建自定义约定,使mongo在此鉴别符字段上显示以实例化正确的子类类型:

public class SubBusinessDiscriminatorConvention : IDiscriminatorConvention
{
    public string ElementName
    {
        get { return "subBusinessName"; }
    }

    public Type GetActualType(BsonReader bsonReader, Type nominalType)
    {
        var bookmark = bsonReader.GetBookmark();
        bsonReader.ReadStartDocument();
        var actualType = nominalType;
        if (bsonReader.FindElement(ElementName))
        {
            var discriminator = (BsonValue)BsonValueSerializer.Instance.Deserialize(bsonReader, typeof(BsonValue), null);
            actualType = BsonSerializer.LookupActualType(nominalType, discriminator);
        }
        bsonReader.ReturnToBookmark(bookmark);
        return actualType;
    }

    public BsonValue GetDiscriminator(Type nominalType, Type actualType)
    {
        var classMap = BsonClassMap.LookupClassMap(actualType);
        return classMap.Discriminator;
    }
}

现在为您的基本类型序列化设置以下约定:

BsonSerializer.RegisterDiscriminatorConvention(typeof(SubBusiness), 
    new SubBusinessDiscriminatorConvention());

您可以按照您的确切格式序列化和反序列化文档。

更新:查询:

var collection = test.GetCollection<STObject>("collectionName");
var sto = collection.FindOne(Query.EQ("_id", new ObjectId("xxxxx")));
var businessList = sto.BusinessList.FirstOrDefault();
var bsub = businessList.SubBuiness.OfType<BsubBusiness>().FirstOrDefault();
var b = bsub.B; // returns bbbbb

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM