我在mongodb中有一个类似于以下内容的文档:
{
"_id": "abcdef01234",
"Name": "Product A",
"Dimensions": [
{
"Height": 32,
"Width": 64
},
{
"Height": 16,
"Width": 32
},
{
"Height": 8,
"Width": 16
}
]
}
我还有一个用于表示维度的类(上面的子文档)
public class Dimension
{
public int Height { get; set; }
public int Width { get; set; }
}
我以这种方式选择“产品A”文件:
MongoServer srv = MongoServer.Create(myConnStr);
BsonDocument doc = srv["db"]["products"].FindOneById(ObjectId.Parse("abcdef01234"));
BsonValue dimensionsVal = doc["Dimensions"];
现在我有一个名为dimensionsVal的BsonValue,其类型为BsonArray。我真正想要的是List< Dimension>。如何将dimensionsVal转换为List< Dimension>?
修改 维度类实际上比我描述的要复杂得多。由于内存问题,我希望将Dimensions与产品分开。我想将产品保留在内存中,但不是(可能是巨大的)维度列表。因此,我不希望将List作为Product类的属性。
答案 0 :(得分:20)
以下是如何做到的:
using MongoDB.Bson.Serialization;
MongoServer srv = MongoServer.Create(myConnStr);
BsonDocument doc = srv["db"]["products"].FindOneById(ObjectId.Parse("abcdef01234"));
BsonValue dimVal = doc["Dimensions"];
List<Dimension> d = BsonSerializer.Deserialize<List<Dimension>>(dimVal.ToJson());
答案 1 :(得分:3)
试试这个:
public class Product
{
[BsonId]
public ObjectId Id { get; set; }
public string Name{ get; set; }
public List<DimensionDoc> Dimensions{ get; set; }
}
public class DimensionDoc
{
public int Height { get; set; }
public int Width { get; set; }
}
Product product = srv["db"]["products"].FindOneByIdAs<Product>(ObjectId.Parse("abcdef01234"));
product.Dimensions现在将包含List&lt;&gt;你需要。
答案 2 :(得分:3)
<强>更新强>
您可能正在寻找include/exclude功能。在c#驱动程序中,它完成了:
// load products without array of Dimensions
MongoCursorInstance.SetFields(Fields.Exclude("Dimensions"));
//load empty product with Dimensions and _id
MongoCursorInstance.SetFields(Fields.Include("Dimensions"));
为什么不为产品创建课程?在这种情况下,驱动程序将能够自动反序列化数据:
class Product
{
[BsonId]
public ObjectId Id { get; set; }
public string Name{ get; set; }
public List<Dimension> Dimensions{ get; set; }
}
var product = srv["db"]["products"].FindOneByIdAs<Product>();
var dimentions = product.Dimensions;
但是如果你不想创建Product
课,你可以这样:
BsonArray dimensionsVal = doc["Dimensions"].AsBsonArray;
var list = new List<Dimension>();
foreach (BsonValue value in dimensionsVal)
{
var bsonDoc = (BsonDocument) value;
var d = new Dimension();
d.Height = bsonDoc["Height"];
d.Width = bsonDoc["Width"];
list.Add(d);
}
答案 3 :(得分:1)
我会使用List&lt; Dimension&gt;类型的Dimensions属性声明您的类。正如其他人提出的那样然后,如果您想要阅读产品而不使用维度值,请写下:
ObjectId productId;
var query = Query.EQ("_id", productId);
var fields = Fields.Exclude("Dimensions");
var product = collection.Find(query).SetFields(fields).FirstOrDefault();
// product.Dimensions will be null because there was no data for it
如果您想阅读完整产品包括所有Dimensions,请写下:
ObjectId productId;
var query = Query.EQ("_id", productId);
var product = collection.FindOne(query);
// product.Dimensions will be populated this time
这比将Dimensions读入BsonDocument并将它们转换为List&lt; Dimension&gt;更有效。用手写的代码。这种方法会导致两个数据副本被加载到内存中(尽管如果你没有保留对它的引用,可能很快就会对BsonDocument版本进行垃圾收集)。