如何强制mongo以小写形式存储成员?

时间:2013-04-12 22:32:23

标签: c# mongodb mongodb-.net-driver mlab

我有一组BsonDocuments,例如:

MongoCollection<BsonDocument> products;

当我插入集合时,我希望成员名称始终为小写。阅读文档后,似乎是ConventionPack的出路。所以,我已经定义了这样一个:

    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方法。

我需要做些什么才能使我的约定有效?

3 个答案:

答案 0 :(得分: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

答案 1 :(得分: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>之前确保您正在注册会议。

答案 2 :(得分:0)

您可以定义ConventionPack,这也是他们关于序列化的官方文档的一部分。就像下面的商店是骆驼大小写的属性名称。您可以在配置服务/存储库时放置

官方链接 https://mongodb.github.io/mongo-csharp-driver/1.11/serialization/[Mongo 数据库序列化 C#]1

            // For MongoDb Conventions
            var pack = new ConventionPack
            {
                new CamelCaseElementNameConvention()
            };

            ConventionRegistry.Register(nameof(CamelCaseElementNameConvention), pack, _ => true);