3

我有一组 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 方法。

我需要做些什么不同的事情才能让我的公约发挥作用?

4

3 回答 3

2

为了使用 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”:

使用 NotText 属性打印出 Foos 表

于 2013-08-14T03:50:30.227 回答
1

如果我理解正确,约定仅在自动映射时应用。如果您有类映射,则需要显式调用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>.

于 2013-05-16T14:55:31.463 回答
0

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

官方链接 https://mongodb.github.io/mongo-csharp-driver/1.11/serialization/[Mongo Db Serialization C#] 1

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

            ConventionRegistry.Register(nameof(CamelCaseElementNameConvention), pack, _ => true);
于 2021-03-11T19:48:16.693 回答