更改 MongoDB 文档中存储为字符串的枚举值

Kit*_*Kit 5 c# enums mongodb mongodb-.net-driver

我有一个类,里面有一个枚举属性。由于以下文档的 .NET 表示形式中的属性,在保存整个文档时,该属性会作为字符串写入数据库

public enum Status { Good, Bad }

public class Document
{
    [BsonRepresentation(BsonType.String)]
    public Status Status { get; set; }
    // ...
}

Run Code Online (Sandbox Code Playgroud)

稍后,当我想要更新文档中的值而不保存整个文档时,我构建一个如下过滤器:

var builder = Builders<T>.Update;
var filter = builder.Set(new StringFieldDefinition<T, Status>(fieldName), (Status)value);
var result = await Context.Collection.UpdateManyAsync(filter, update);
Run Code Online (Sandbox Code Playgroud)

不幸的是,这会写入枚举的整数值。

如果我将过滤器更改为这个

var filter = builder.Set(new StringFieldDefinition<T, Status>(fieldName), value.ToString());
Run Code Online (Sandbox Code Playgroud)

司机会抛出一个InvalidCastException。如何正确构建过滤器?有没有另一种方法可以直接设置枚举值而不替换文档?

我想到可能有一种方法可以将单字段行为与整个文档的属性相关联,但我似乎不知道如何做到这一点。

Dĵ *_*ΛψΚ 3

一旦你装饰了一个枚举属性,[BsonRepresentation(BsonType.String)]你就不需要在代码中进行任何转换。该属性指示驱动程序将枚举值的搅拌名称存储在数据库中,并在反序列化时将其设置回适当的枚举值。所以你的应用程序代码可以只处理枚举。

    var statusValue = Status.Good;

    var filter = Builders<Document>.Filter.Eq(d => d.Status, Status.Bad);
    var update = Builders<Document>.Update.Set(d => d.Status, statusValue);

    collection.UpdateMany(filter, update);
Run Code Online (Sandbox Code Playgroud)

测试程序:

using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
using MongoDB.Entities;
using MongoDB.Entities.Core;

namespace StackOverFlow
{
    public enum Status { Good, Bad }

    public class Document : Entity
    {
        [BsonRepresentation(BsonType.String)]
        public Status Status { get; set; }
    }

    public static class Program
    {
        private static void Main()
        {
            new DB("test");

            new Document { Status = Status.Bad }.Save();

            var statusValue = Status.Good;

            DB.Update<Document>()
              .Match(f => f.Eq(d => d.Status, Status.Bad))
              .Modify(b => b.Set(d => d.Status, statusValue))
              .Execute();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)