簡體   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