C#+ MongoDB-不使用MongoDB数据类型/属性的ObjectId [英] C# + MongoDB - ObjectId without using MongoDB DataTypes/Attributes

查看:552
本文介绍了C#+ MongoDB-不使用MongoDB数据类型/属性的ObjectId的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用MongoDB作为我的数据存储,默认情况下使我具有ObjectID类型作为主键.也可以通过将Guid与[BsonId]属性一起使用来更改它. MongoDB C#驱动程序库中也定义了该库.我想让我的实体独立于数据层. 我可以仅使用属性的名称ID来标识主键吗?我还能尝试什么?

Using MongoDB as my data store makes me to have ObjectID type as primary key by Default. It also can be changed by using Guid with [BsonId] attribute. Which is also defined in MongoDB C# Driver library. I would like to have my Entities independent from Data layer. Can I just use name Id for the property to identify primary key? What else I can try?

推荐答案

选项1:坚持使用BsonId并使用外观模式

[BsonId]属性是用于指示_id属性应链接到特定属性的属性.没有办法解决这个问题(在您的操作中完全忽略_id似乎是个坏主意).

OPTION 1: Stick with BsonId and use the Facade Pattern

The [BsonId] property is what you'd use to indicate that the _id property should be linked to a specific property. There isn't a way around that (short of ignoring _id entirely in your crud operations which seems like a bad idea).

因此,如果要将实体"对象与数据层"分开,则只需使用poco类.

So, if you want to separate your "entity" object from your "data layer" then just use a poco class.

-使用

-- Use a poco class as a substitute for a record. That class is only for data storage: a quick way to get data in/out of mongo, and a great alternative to working with bson documents.

-在该poco类的顶部为您的实体层使用外观.我认为重新发明轮子没什么用,所以我通常会问我们的开发人员让实体接口继承数据层(poco)接口,但是您可以根据自己的意愿做

-- Use a facade on top of that poco class for your entity layer. I don't find it useful to re-invent the wheel, so I typically ask our devs have the entity interface inherit the data-layer (poco) interface, but you can do it however you'd like

IMyObjectRecord (在dal声明,仅包含属性和mongo特定的属性)

IMyObjectRecord (declared at the dal and contains only properties and mongo-specific attributes)

IMyObject:IMyObjectRecord (在实体级别声明,可能包括添加的属性和方法)

IMyObject:IMyObjectRecord (declared at the entity level and may include added properties and methods)

MyObjectRecord:IMyObjectRecord (在dal内声明,包含mongo特定的属性.如果您想严格限制分隔,可以声明为内部).

MyObjectRecord:IMyObjectRecord (declared inside the dal, contains mongo-specific attributes. Could be declared internal if you wanted to be really strict about separation).

MyObject:IMyObject (例如,可以是从dal拉出的IMyObjectRecord类顶部的外观).

MyObject:IMyObject (could be, for example, a facade on top of the IMyObjectRecord class you pull from the dal).

现在-您可以获得外观的所有优点,并且在属性BUT之间具有硬编码链接,可以将dalson属性保留在dal中.

Now - you get all the benefits of the facade, and you have a hard-coded link between the properties BUT, you get to keep Bson attributes contained in your dal.

是的.我可以接受. 好,那么约定包怎么样?:如果您完全承诺将您的ID称为"Id",并且发誓要将其键入为字符串(或者-使用其他一些约定,很容易识别),那么我们可以使用约定包像我从这里偷来的包

Yeah. I can accept that. OK, so how about a Convention Pack? If you ABSOLUTELY PROMISE that you'll call your Id's "Id" and you SWEAR that you'll type them as strings (or -- use some other convention that is easy to identify), then we could just use a convention pack like the one I stole from here

namespace ConsoleApp {
    class Program {

        private class Foo {
            // Look Ma!  No attributes!
            public string Id { get; set; }
            public string OtherProperty { get; set; }
        }

        static void Main(string[] args) {

            //you would typically do this in the singleton routine you use 
            //to create your dbClient, so you only do it the one time.
            var pack = new ConventionPack();   
            pack.Add(new StringObjectIdConvention());
            ConventionRegistry.Register("MyConventions", pack, _ => true);
            // Note that we registered that before creating our client...
            var client = new MongoClient();

            //now, use that client to create collections
            var testDb = client.GetDatabase("test");
            var fooCol = testDb.GetCollection<Foo>("foo");
            fooCol.InsertOne(new Foo() { OtherProperty = "Testing", Id="TEST" });

            var foundFoo = fooCol.Find(x => x.OtherProperty == "Testing").ToList()[0];
            Console.WriteLine("foundFooId: " + foundFoo.Id);
       }

        //obviously, this belongs in that singleton namespace where
        //you're getting your db client.
        private class StringObjectIdConvention : ConventionBase, IPostProcessingConvention {
            public void PostProcess(BsonClassMap classMap) {
                var idMap = classMap.IdMemberMap;
                if (idMap != null && idMap.MemberName == "Id" && idMap.MemberType == typeof(string)) {
                    idMap.SetIdGenerator(new StringObjectIdGenerator());
                }
            }
        }
    }
}

什么是公约包

这是在序列化/反序列化过程中应用的少量mongo规则".您只需注册一次(设置引擎时).在这种情况下,示例包告诉mongo如果您看到一个名为'Id'的字段,请将该字段另存为_id."

What's a Convention Pack

It's a little set of mongo "rules" that get applied during serialize/deserialize. You register it once (when you setup your engine). In this case, the sample pack is telling mongo "if you see a field called 'Id', then save it as a string to _id, please."

这些会变得非常复杂和有趣.如果您真的非常讨厌其他方法,那么我将深入探讨惯例包.这是将所有mongo属性驱动"逻辑强制到一个独立位置的好方法.

These can get really complex and fun. I'd dig into convention packs if you really really really hate the other approach. It's a good way to force all your mongo "attribute driven" logic into one self-contained location.

这篇关于C#+ MongoDB-不使用MongoDB数据类型/属性的ObjectId的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆