存储复合/嵌套对象图

发布于 2024-11-29 23:43:21 字数 2703 浏览 1 评论 0原文

我目前正在 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" : []
                        }
                    ]
                }
            ]
        }
    ]
}

可能是什么问题?

I am currently developing a document store in Mongo DB which contains a complete material breakdown of a specific item. The breakdown is calculated and contains a composite structure.

The domain model:

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; }
}

Now the problem is that a composite structure is not correctly stored. Reagents stays null in mongodb.

/* 28 */
{
  "_id" : ObjectId("4e497efa97e8b617f0d229d4"),
  "ItemId" : 52186,
  "Quantity" : 0,
  "SpellId" : 0,
  "Skill" : 475,
  "Profession" : 8,
  "Reagents" : { }
}

Example of how it should look

{
    "_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" : []
                        }
                    ]
                }
            ]
        }
    ]
}

What could be the problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

挽心 2024-12-06 23:43:21

问题是您正在使用抽象列表,并且它无法将它们序列化为 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();
        }

    }

在您的情况下,我将在试剂类级别编写自定义序列化

The problem is you are using list of abstractions and it cannot serialize these to JSON, so basically you would need to write your own custom serialization. Here is example of custom serialization I wrote:

 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();
        }

    }

In your case I would write my custom serialization on the level of Reagent class

月下客 2024-12-06 23:43:21

实现 IBsonSerializer 有效:)做了一个快速的模拟,效果非常好:DI 从某人那里得到了另一个建议,他说 List 可以工作,本周晚些时候会尝试一下。并将结果发布在这里。

/* 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" : []
                }]
            }]
        }]
    }]
}

序列化实现:

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();

}

Implenting IBsonSerializer worked :) Did a quick mock up and it worked pretty well :D I got another suggestion from someone who says a List<T> would work, gonna try that later this week. And post the results here.

/* 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" : []
                }]
            }]
        }]
    }]
}

Serialization 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();

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文