我目前正在Mongo DB中开发一个文档存储,其中包含特定项目的完整材料细分。细分计算并包含复合结构。
域名模型:
public interface IReagent
{
int ItemId { get; set; }
int Quantity { get; set; }
ConcurrentBag<IReagent> Reagents { get; set; }
}
public class Craft : IReagent
{
public int ItemId { get; set; }
public int Quantity { get; set; }
public int SpellId { get; set; }
public int Skill { get; set; }
public Profession Profession { get; set; }
public ConcurrentBag<IReagent> Reagents { get; set; }
}
public class Reagent : IReagent
{
public int ItemId { get; set; }
public int Quantity { get; set; }
public ConcurrentBag<IReagent> Reagents { get; set; }
}
现在的问题是没有正确存储复合结构。 mongodb中的试剂保持为空。
/* 28 */
{
"_id" : ObjectId("4e497efa97e8b617f0d229d4"),
"ItemId" : 52186,
"Quantity" : 0,
"SpellId" : 0,
"Skill" : 475,
"Profession" : 8,
"Reagents" : { }
}
它的外观示例
{
"_id" : ObjectId("4e497efa97e8b617f0d229d4"),
"ItemId" : 52186,
"Quantity" : 0,
"SpellId" : 0,
"Skill" : 475,
"Profession" : 8,
"Reagents" : [
{
"ItemId" : 521833,
"Quantity" : 3,
"SpellId" : 0,
"Skill" : 400,
"Profession" : 7,
"Reagents" : [
{
"ItemId" : 52186,
"Quantity" : 3,
"SpellId" : 0,
"Skill" : 475,
"Profession" : 8,
"Reagents" : [
{
"ItemId" : 52183,
"Quantity" : 2,
"Reagents" : []
},
{
"ItemId" : 521832,
"Quantity" : 1,
"Reagents" : []
}
]
},
{
"ItemId" : 52386,
"Quantity" : 2
"SpellId" : 0,
"Skill" : 400,
"Profession" : 8,
"Reagents" : [
{
"ItemId" : 52383,
"Quantity" : 2,
"Reagents" : []
},
{
"ItemId" : 523832,
"Quantity" : 1,
"Reagents" : []
}
]
}
]
}
]
}
可能是什么问题?
答案 0 :(得分:2)
问题是你正在使用抽象列表,它不能将这些序列化为JSON,所以基本上你需要编写自己的自定义序列化。以下是我写的自定义序列化示例:
public class FieldsWrapper : IBsonSerializable
{
public List<DataFieldValue> DataFieldValues { get; set; }
public object Deserialize(MongoDB.Bson.IO.BsonReader bsonReader, Type nominalType, IBsonSerializationOptions options)
{
if (nominalType != typeof(FieldsWrapper)) throw new ArgumentException("Cannot deserialize anything but self");
var doc = BsonDocument.ReadFrom(bsonReader);
var list = new List<DataFieldValue>();
foreach (var name in doc.Names)
{
var val = doc[name];
if (val.IsString)
list.Add(new DataFieldValue {LocalIdentifier = name, Values = new List<string> {val.AsString}});
else if (val.IsBsonArray)
{
DataFieldValue df = new DataFieldValue {LocalIdentifier = name};
foreach (var elem in val.AsBsonArray)
{
df.Values.Add(elem.AsString);
}
list.Add(df);
}
}
return new FieldsWrapper {DataFieldValues = list};
}
public void Serialize(MongoDB.Bson.IO.BsonWriter bsonWriter, Type nominalType, IBsonSerializationOptions options)
{
if (nominalType != typeof (FieldsWrapper))
throw new ArgumentException("Cannot serialize anything but self");
bsonWriter.WriteStartDocument();
foreach (var dataFieldValue in DataFieldValues)
{
bsonWriter.WriteName(dataFieldValue.LocalIdentifier);
if (dataFieldValue.Values.Count != 1)
{
var list = new string[dataFieldValue.Values.Count];
for (int i = 0; i < dataFieldValue.Values.Count; i++)
list[i] = dataFieldValue.Values[i];
BsonSerializer.Serialize(bsonWriter, list);
}
else
{
BsonSerializer.Serialize(bsonWriter, dataFieldValue.Values[0]);
}
}
bsonWriter.WriteEndDocument();
}
}
在你的情况下,我会在Reagent类的水平上编写自定义序列化
答案 1 :(得分:0)
实施IBsonSerializer工作:)做了一个快速的模拟并且它工作得很好:D我得到了另一个说List<T>
会工作的人的建议,本周晚些时候会尝试。并在此处发布结果。
/* 3131 */
{
"_id" : ObjectId("4e4d58df77d2cf00691aaef2"),
"ItemId" : 28432,
"Quantity" : 0,
"Reagents" : [{
"ItemId" : 23448,
"Quantity" : 0,
"Reagents" : [{
"ItemId" : 23447,
"Quantity" : 0,
"Reagents" : [{
"ItemId" : 23427,
"Quantity" : 2,
"Reagents" : []
}]
}, {
"ItemId" : 23445,
"Quantity" : 0,
"Reagents" : [{
"ItemId" : 23424,
"Quantity" : 2,
"Reagents" : []
}]
}]
}, {
"ItemId" : 23572,
"Quantity" : 8,
"Reagents" : []
}, {
"ItemId" : 28431,
"Quantity" : 0,
"Reagents" : [{
"ItemId" : 23571,
"Quantity" : 0,
"Reagents" : [{
"ItemId" : 21885,
"Quantity" : 1,
"Reagents" : []
}, {
"ItemId" : 21884,
"Quantity" : 1,
"Reagents" : []
}, {
"ItemId" : 22451,
"Quantity" : 0,
"Reagents" : [{
"ItemId" : 21885,
"Quantity" : 1,
"Reagents" : []
}]
}, {
"ItemId" : 22452,
"Quantity" : 1,
"Reagents" : []
}, {
"ItemId" : 22457,
"Quantity" : 0,
"Reagents" : [{
"ItemId" : 21884,
"Quantity" : 1,
"Reagents" : []
}]
}]
}, {
"ItemId" : 22456,
"Quantity" : 0,
"Reagents" : [{
"ItemId" : 21885,
"Quantity" : 1,
"Reagents" : []
}]
}, {
"ItemId" : 23573,
"Quantity" : 0,
"Reagents" : [{
"ItemId" : 23446,
"Quantity" : 0,
"Reagents" : [{
"ItemId" : 23425,
"Quantity" : 2,
"Reagents" : []
}]
}]
}, {
"ItemId" : 23448,
"Quantity" : 0,
"Reagents" : [{
"ItemId" : 23447,
"Quantity" : 0,
"Reagents" : [{
"ItemId" : 23427,
"Quantity" : 2,
"Reagents" : []
}]
}, {
"ItemId" : 23445,
"Quantity" : 0,
"Reagents" : [{
"ItemId" : 23424,
"Quantity" : 2,
"Reagents" : []
}]
}]
}]
}]
}
序列化impl:
public void Serialize(MongoDB.Bson.IO.BsonWriter bsonWriter, Type nominalType, MongoDB.Bson.Serialization.IBsonSerializationOptions options)
{
if (nominalType != typeof(IReagent) && nominalType != typeof(Reagent) && nominalType != typeof(Craft))
{
throw new ArgumentException("Cannot serialize anything but self");
}
bsonWriter.WriteStartDocument();
bsonWriter.WriteInt32("ItemId", this.ItemId);
bsonWriter.WriteInt32("Quantity", this.Quantity);
if (this.Reagents != null)
{
bsonWriter.WriteName("Reagents");
bsonWriter.WriteStartArray();
foreach (var r in this.Reagents)
{
BsonSerializer.Serialize(bsonWriter, r.GetType(), r, options);
}
bsonWriter.WriteEndArray();
}
bsonWriter.WriteEndDocument();
}