我正在编写写入现有 Web 应用程序(用 PHP 编写)使用的 Mongo 数据库的 C# 代码,因此我不需要更改数据库的现有结构。数据库结构如下所示:
{
"_id": ObjectId("5572ee670e86b8ec0ed82c61")
"name": "John Q. Example",
"guid": "12345678-1234-5678-abcd-fedcba654321",
"recordIsDeleted": false,
"address":
{
"line1": "123 Main St.",
"city": "Exampleville"
}
}
我把它读到一个看起来像这样的类中:
public class Person : MongoMappedBase
{
public ObjectId Id { get; set; }
public Guid Guid { get; set; }
public bool RecordIsDeleted { get; set; }
public string Name { get; set; }
public AddressData Address { get; set; }
// etc.
}
public class AddressData : MongoMappedBase
{
public string Line1 { get; set; }
public string City { get; set; }
// etc.
}
阅读代码如下:
var collection = db.GetCollection<Person>("people");
List<Person> people = collection.Find<Person>(_ => true).ToListAsync().Result;
(注意:我仍在开发中。在生产中,我将一次切换到ToCursorAsync()
并循环一个数据,所以不用担心我会将整个列表拉入内存。)
到目前为止,一切都很好。
但是,当我写出数据时,它是这样的:
{
"_id": ObjectId("5572ee670e86b8ec0ed82c61")
"name": "John Q. Example",
"guid": "12345678-1234-5678-abcd-fedcba654321",
"recordIsDeleted": false,
"address":
{
"_t": "MyApp.MyNamespace.AddressData, MyApp",
"_v":
{
"line1": "123 Main St.",
"city": "Exampleville"
}
}
}
请注意该address
字段的外观有何不同。那不是我想要的。我希望地址数据看起来就像地址数据输入(否_t
或_v
字段)。换句话说,最终作为内容的部分_v
是我想作为字段值保存到 Mongo 数据库中的内容address
。
现在,如果我只是从我自己的 C# 代码中使用 Mongo 数据库,这可能会很好:如果我要反序列化这个数据结构,我假设(虽然我还没有验证)Mongo 将使用_t
and_v
字段来创建正确类型 ( AddressData
) 的实例,并将它们放在我的实例的Address
属性中。Person
在这种情况下,一切都会好起来的。
但我正在与一个 PHP Web 应用程序共享这个数据库,该应用程序不希望在地址数据中看到这些_t
和_v
值,也不知道如何处理它们。我需要告诉 Mongo “请不要序列化Address
属性的类型。假设它总是一个AddressData
实例,并且只序列化它的内容而没有任何鉴别器。”
我目前用来将对象持久保存到 Mongo 的代码如下所示:
public UpdateDefinition<TDocument> BuildUpdate<TDocument>(TDocument doc) {
var builder = Builders<TDocument>.Update;
UpdateDefinition<TDocument> update = null;
foreach (PropertyInfo prop in typeof(TDocument).GetProperties())
{
if (prop.PropertyType == typeof(MongoDB.Bson.ObjectId))
continue; // Mongo doesn't allow changing Mongo IDs
if (prop.GetValue(doc) == null)
continue; // If we didn't set a value, don't change existing one
if (update == null)
update = builder.Set(prop.Name, prop.GetValue(doc));
else
update = update.Set(prop.Name, prop.GetValue(doc));
}
return update;
}
public void WritePerson(Person person) {
var update = BuildUpdate<Person>(person);
var filter = Builders<Person>.Filter.Eq(
"guid", person.Guid.ToString()
);
var collection = db.GetCollection<Person>("people");
var updateResult = collection.FindOneAndUpdateAsync(
filter, update
).Result;
}
在那里的某个地方,我需要告诉 Mongo“我不关心属性_t
上的字段Address
,我什至不想看到它。我知道我在这个字段中坚持什么类型的对象,他们”永远都是一样的。” 但是我还没有在 Mongo 文档中找到任何东西来告诉我如何做到这一点。有什么建议么?