默认MongoDB公共属性的序列化

时间:2012-09-04 12:16:34

标签: c# mongodb serialization

据我所知,我的类必须具有公共读写属性,以便MongoDB驱动程序对我的对象进行序列化/反序列化。但我想知道是否有方法/首选方法从我的其余代码中隐藏写属性?

例如

class Product
{
    private List<Release> releases;

    public List<Release> Releases
    {
        get
        {
            return new List<Release>(releases); //I can protect 'releases' when reading by passing a copy of it
        }
        set
        {
            releases = value; //BUT how can I protect release when writing?
        }
    }
}

我希望MongoDB能够序列化/反序列化我的类型,但我不希望我的其余代码能够覆盖它本来应该是私有的字段/属性。有处理这个的模式吗?我曾想过有一个单独的ProductDoc类,它只是用作将对象放入和放出MongoDB的中介,但我不确定是否有更好的解决方案。

3 个答案:

答案 0 :(得分:5)

我暂时没有和mongo合作过很长时间。但是你可能会尝试阅读这个帖子MongoDb Map Setters或尝试让你的setter像这样受到保护:

public List<Release> Releases
{
    get
    {
        return new List<Release>(releases); //I can protect 'releases' when reading by passing a copy of it
    }
    protected set
    {
        releases = value; //BUT how can I protect release when writing?
    }
}

答案 1 :(得分:2)

另一种方法,如果你的属性是由构造函数设置的,那就是让它们保持只读,并使用MapCreator告诉MongoDB如何创建一个类的实例,传递你想要设置的属性。

e.g。我有一个名为Time的类,它有三个只读属性:HourMinuteSecond以及需要一小时,一分钟和第二个值的公共构造函数。

以下是我如何让MongoDB将这三个值存储在数据库中以及在反序列化过程中构造新的Time对象。

BsonClassMap.RegisterClassMap<Time>(cm =>
{
    cm.AutoMap();
    cm.MapCreator(p => new Time(p.Hour, p.Minute, p.Second));
    cm.MapProperty(p => p.Hour);
    cm.MapProperty(p => p.Minute);
    cm.MapProperty(p => p.Second);
}

答案 2 :(得分:1)

此页面上的最佳答案目前存在一些很难理解的缺陷。

目前正在编写解决方案:

public List<Release> Releases
{
    get
    {
        return new List<Release>(releases); //I can protect 'releases' when reading by passing a copy of it
    }
    protected set
    {
        releases = value; //BUT how can I protect release when writing?
    }
}

这不符合书面形式。

obj.Releases.Add(new Release());

会通过向其添加新版本来影响基础集合。这与将设置例程设为私有的既定目标直接矛盾。

但是,如果更改公开的属性类型以实现IEnumerable而不是List并返回列表的ReadOnly版本。比如...

public IEnumerable<Release> Releases
{
    get
    {
        return new List<Release>(releases).AsReadOnly();
    }
    protected set
    {
        releases = value;
    }
}

然后两个

obj.Releases.Add(new Release());

obj.Releases = new List<Release>();

将抛出构建错误并阻止修改底层集合。