2015-10-30 2 views
1

Я пишу код C#, чтобы вытащить данные из существующей базы данных MongoDB и поместить ее в различные классы C#. Одна часть базы данных является полиморфной: если поле type равно A, то в этом документе будет существовать определенный набор полей. Если type - B, то будет существовать другой набор полей. Это идеальный вариант использования для ScalarDiscriminatorConvention, поэтому я использую ScalarDiscriminatorConvention("type"). Но я не знаю, как заставить использовать драйвер MongoDB!Как зарегистрировать ScalarDiscriminatorConvention для другого имени поля в 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, и я совершенно не понимаю. Кажется, они не документировали нигде, что я мог найти.

+0

Документов здесь: http://mongodb.github.io/mongo-csharp- водитель/2,1/ссылка/BSON/отображение/полиморфизма /. Однако, похоже, это не документировано ... Я найду дополнительную информацию. –

+0

@CraigWilson - Да, эта страница может означать функцию «BsonSerializer.RegisterDiscriminatorConvention». В отсутствие такого упоминания я думал, что мне нужно добавить его в «ConventionPack», как и все другие объекты «FooConvention», и я спустился по нескольким кроличьим тропам, пытаясь понять это. – rmunn

+0

@CraigWilson - только что созданный https://jira.mongodb.org/browse/CSHARP-1465 для отслеживания этой потребности в документации. – rmunn

ответ

2

Соглашения о дискриминаторе отдельно от конвенций сопоставления классов. Я предполагаю, что ваши классы A и B происходят от общего базового класса:

public class BaseClass 
{ 
    public int Id; 
} 

public class A : BaseClass 
{ 
    public int FA; 
} 

public class B : BaseClass 
{ 
    public int FB; 
} 

Я также предполагаю, что вы хотите, чтобы имя дискриминатор поле, чтобы быть «тип» вместо по умолчанию «_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); 
+1

Спасибо. Вызов «BsonSerializer.RegisterDiscriminatorConvention» в базовом классе был именно тем, что мне нужно. Теперь, когда я знаю, что искать, я могу найти его в документации API, но я не мог найти его нигде в справочной документации, где раньше смотрел. Вы мне очень помогли! – rmunn

Смежные вопросы