2013-04-12 2 views
2

У меня есть коллекция BsonDocuments, например:Как заставить монго хранить элементы в нижнем регистре?

MongoCollection<BsonDocument> products; 

Когда я делаю вставки в коллекцию, я хочу, чтобы имя члена, чтобы всегда быть в нижнем регистре. После прочтения документации, похоже, что Конвенция - это путь. Итак, я определил один, как это:

public class LowerCaseElementNameConvention : IMemberMapConvention 
{ 
    public void Apply(BsonMemberMap memberMap) 
    { 
     memberMap.SetElementName(memberMap.MemberName.ToLower()); 
    } 

    public string Name 
    { 
     get { throw new NotImplementedException(); } 
    } 
} 

И сразу после того, как я получу свой экземпляр коллекции зарегистрировать соглашение, как это:

 var pack = new ConventionPack(); 
     pack.Add(new LowerCaseElementNameConvention()); 
     ConventionRegistry.Register(
      "Product Catalog Conventions", 
      pack, 
      t => true); 

К сожалению, это имеет нулевое влияние на то, что хранится в моя коллекция. Я отладил его и обнаружил, что метод Apply никогда не вызывается.

Что мне нужно сделать по-другому, чтобы заставить мое соглашение работать?

+1

Какой драйвер вы используете? Похоже на конкретный вопрос для водителя. Похож на C#, но я могу ошибаться. Я рекомендую добавлять теги для языка/драйвера, чтобы привлечь нужных читателей. – jared

+0

Да, это драйвер C# (v1.8). –

+0

Прохладный, я просто переделал его для вас. Мы посмотрим, привлекает ли это людей, которые хорошо осведомлены в драйвере C#. – jared

ответ

0

Если я правильно понимаю, соглашения применяются только при автоматическом сопоставлении. Если у вас есть карта классов, вам нужно явно позвонить AutoMap(), чтобы использовать соглашения. После этого вы можете изменить Автоотображение и т.д .:

public class MyThingyMap : BsonClassMap<MyThingy> 
{ 
    public MyThingyMap() 
    { 
     // Use conventions to auto-map 
     AutoMap(); 

     // Customize automapping for specific cases 
     GetMemberMap(x => x.SomeProperty).SetElementName("sp"); 
     UnmapMember(x => x.SomePropertyToIgnore); 
    } 
} 

Если вы не включили карту класса, я думаю, что по умолчанию является просто использовать Автоотображение, в этом случае следует применять ваши конвенции. Перед вызовом GetCollection<T> убедитесь, что вы зарегистрировали соглашение.

1

Чтобы использовать IMemeberMapConvention, вы должны обязательно объявить свои соглашения до того, как произойдет процесс сопоставления. Или, возможно, удалить существующие сопоставления и создать новые.

Например, следующий правильный порядок применения конвенции:

 // first: create the conventions 
     var myConventions = new ConventionPack(); 
     myConventions.Add(new FooConvention()); 

     ConventionRegistry.Register(
      "My Custom Conventions", 
      myConventions, 
      t => true); 

     // only then apply the mapping 
     BsonClassMap.RegisterClassMap<Foo>(cm => 
     { 
      cm.AutoMap(); 
     }); 

     // finally save 
     collection.RemoveAll(); 
     collection.InsertBatch(new Foo[] 
           { 
            new Foo() {Text = "Hello world!"}, 
            new Foo() {Text = "Hello world!"}, 
            new Foo() {Text = "Hello world!"}, 
           }); 

Вот как было определено в данном примере конвенции:

public class FooConvention : IMemberMapConvention 

    private string _name = "FooConvention"; 

    #region Implementation of IConvention 

    public string Name 
    { 
     get { return _name; } 
     private set { _name = value; } 
    } 

    public void Apply(BsonMemberMap memberMap) 
    { 
     if (memberMap.MemberName == "Text") 
     { 
      memberMap.SetElementName("NotText"); 
     } 
    } 

    #endregion 
} 

Таковы результаты, которые вышли, когда я побежал этот образец. Вы могли видеть, свойство Text закончилось тем, что был сохранен как «NotText»:

Print out of Foos table with NotText properties

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