簡體   English   中英

MongoDB驅動程序無法在通過ID過濾期間將自定義序列化程序轉換為IBsonSerializer

[英]MongoDB driver unable cast custom serializer to IBsonSerializer during filter by Id

我正在使用C#開發應用程序。 我在從MongoDB獲取Id的文檔時遇到問題。

我的ID不是ObjectId,而是Guid。

模型是簡單的POCO。

public class Folder
{
        public Guid Id { get; set; }
        public int OrgId { get; set; }
        // rest props is not important
}

在創建存儲庫實例(靜態構造函數)的過程中,我注冊了類映射:

    static MongoDBFolderRepository()
    {
        Init();
    }

    private static void Init()
    {
        var camelCaseConvention = new ConventionPack { new CamelCaseElementNameConvention() };
        ConventionRegistry.Register("CamelCase", camelCaseConvention, type => true);

        BsonClassMap.RegisterClassMap<Folder>(cm =>
        {
            cm.AutoMap();
            cm.MapIdMember(c => c.Id).SetSerializer(new MyGuidSerializer());
            cm.SetIgnoreExtraElements(true);
        });
    }

而且我還指定了自己的序列化器:

[BsonSerializer(typeof(MyGuidSerializer))]
public class MyGuidSerializer : IBsonSerializer
{
    public object Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
    {
        return Guid.Parse(BsonSerializer.Deserialize<string>(context.Reader));
    }

    public void Serialize(BsonSerializationContext context, BsonSerializationArgs args, object value)
    {
        BsonSerializer.Serialize(context.Writer, value.ToString());
    }

    public Type ValueType
    {
        get { return typeof(Guid); }
    }
}

現在,這是引發異常的方法:

public async Task<Folder> GetFolderAsync(Guid folderId)
{
    var database = MongoDBHelper.GetDatabase();
    var collection = database.GetCollection<Folder>(CollectionName);
    return await collection.Find(Builders<Folder>.Filter.Eq(x => x.Id, folderId)).SingleAsync();
}

例外是:

無法將類型為“ MyApp.Repositories.Reporting.Concrete.MyGuidSerializer”的對象轉換為類型為“ MongoDB.Bson.Serialization.IBsonSerializer`1 [System.Guid]”的對象。

System.InvalidCastException

通常,序列化是可行的。 如果我將方法更改為此版本:

    public async Task<Folder> GetFolderAsync(Guid folderId)
    {
        var database = MongoDBHelper.GetDatabase();
        var collection = database.GetCollection<Folder>(CollectionName);
        return await collection.Find(Builders<Folder>.Filter.Eq("_id", folderId.ToString())).SingleAsync();
    }

我將得到正確填充的Folder模型作為回報。

我做錯了什么 ?

為什么首先要嘗試序列化為string

您只需通過直接對Guid進行序列化/反序列化就可以解決您的問題:

public void Serialize(BsonSerializationContext context, BsonSerializationArgs args, Guid value)
    {
        var data = new BsonBinaryData(value);
        context.Writer.WriteBinaryData(data);
    }

public object Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
    {
        return BsonSerializer.Deserialize<Guid>(context.Reader);
    }

我不知道為什么,但是在更改IBsonSerializer<Guid>接口后,所有方法都可以使用。

[BsonSerializer(typeof(MyGuidSerializer))]
public class MyGuidSerializer : IBsonSerializer<Guid>
{
    public object Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
    {
        return Guid.Parse(BsonSerializer.Deserialize<string>(context.Reader));
    }

    public void Serialize(BsonSerializationContext context, BsonSerializationArgs args, Guid value)
    {
        BsonSerializer.Serialize(context.Writer, value.ToString());
    }

    Guid IBsonSerializer<Guid>.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
    {
        return Guid.Parse(BsonSerializer.Deserialize<string>(context.Reader));
    }

    public void Serialize(BsonSerializationContext context, BsonSerializationArgs args, object value)
    {
        BsonSerializer.Serialize(context.Writer, value.ToString());
    }

    public Type ValueType
    {
        get { return typeof(Guid); }
    }
}

一般通用接口繼承IBsonSerializer,所以我不明白為什么,如果我實現IBsonSerializer為MyGuidSerializer我Unable cast to IBsonSerializer

是的,但是將實現的接口從IBsonSerializer更改為IBsonSerializer<Guid>解決問題。

Mongodb.CsharpDriver 2.4.4

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM