如何在MongoDB中为不同的字段名注册ScalarDiscriminatorConvention?

时间:2015-10-30 09:43:44

标签: c# mongodb mongodb-.net-driver mongodb-csharp-2.0

我正在编写C#代码以从现有的MongoDB数据库中提取数据并将其放入各种C#类中。数据库的一部分是多态的:如果字段type是A,那么该文档中将存在一组特定的字段。如果type为B,则将存在一组不同的字段。这是ScalarDiscriminatorConvention的完美用例,因此我使用ScalarDiscriminatorConvention("type")。但我不知道如何让MongoDB驱动程序使用该约定!

The MongoDB manual page on conventions让我觉得这样可行:

var pack = new ConventionPack();
pack.Add(new CamelCaseElementNameConvention());
pack.Add(new ScalarDiscriminatorConvention("type"));

ConventionRegistry.Register(
    "My Custom Conventions",
    pack,
    t => t.FullName.StartsWith("MyNamespace."));

但是这失败了,因为ScalarDiscriminatorConvention并不像其他约定那样从IConvention接口派生出来。它派生自IDiscriminatorConvention,它是自己的接口,不是从IConvention派生的。 ConventionPack.Add需要IConvention参数。

那么如何注册不同的鉴别字段?我现在已经通过MongoDB手册搜索了至少一个小时,而且我很茫然。他们似乎没有记录在我能找到的任何地方。

1 个答案:

答案 0 :(得分:2)

判别器约定与类映射约定分开。我假设你的A和B类派生自一个共同的基类:

public class BaseClass
{
    public int Id;
}

public class A : BaseClass
{
    public int FA;
}

public class B : BaseClass
{
    public int FB;
}

我还假设您希望鉴别器字段名称为" type"而不是默认的" _t"。

您将为基类注册一个鉴别器约定,如下所示:

BsonSerializer.RegisterDiscriminatorConvention(typeof(BaseClass), new ScalarDiscriminatorConvention("type"));

您现在可以序列化和反序列化BaseClass值和"类型"字段将包含" A"或" B"取决于值的实际类型。

我使用以下代码验证序列化表单并验证序列化表单是否可以反序列化:

BaseClass a = new A { Id = 1, FA = 1 };
var jsonA = a.ToJson();
var deserializedA = BsonSerializer.Deserialize<BaseClass>(jsonA);

BaseClass b = new B { Id = 2, FB = 2 };
var jsonB = b.ToJson();
var deserializedB = BsonSerializer.Deserialize<BaseClass>(jsonB);