簡體   English   中英

C# mongodb 使用記錄的強類型 ID

[英]C# mongodb with strongly typed ID using records

我正在使用帶有 Mongo 的 C#9 記錄來處理強類型 ID。 我已經成功地完成了插入工作,但讀取時拋出了異常(見下文)。

這些是 model 定義。 非常簡單, TestModel有一個類型為StronglyTypedId<Guid>TestModelId

public record TestModel(TestModelId Id, string value, string? value1);
public record TestModelId(Guid Id) : StronglyTypedId<Guid>(Id);
public abstract record StronglyTypedId<TValue>(TValue Id) where TValue : notnull;

這些需要注冊序列化提供程序和序列化程序 class。

登記:

var guidSerializer = BsonSerializer.SerializerRegistry.GetSerializer<Guid>();
BsonSerializer.RegisterSerializationProvider(new IdSerializationProvider(guidSerializer));

序列化程序:

public class IdSerializationProvider : IBsonSerializationProvider
{
    private IBsonSerializer<Guid> guidSerializer;

    public IdSerializationProvider(IBsonSerializer<Guid> guidSerializer)
    {
        this.guidSerializer = guidSerializer;
    }

    public IBsonSerializer? GetSerializer(Type type)
    {
        if(type.BaseType != null && type.BaseType == typeof(StronglyTypedId<Guid>)) 
            return new TestModelSerializer(type, guidSerializer);
        
        return null;
    }
}

public class TestModelSerializer : SerializerBase<StronglyTypedId<Guid>>
{
    private readonly Type targetType;
    private readonly IBsonSerializer<Guid> guidSerializer;

    public TestModelSerializer(Type targetType, IBsonSerializer<Guid> guidSerializer)
    {
        this.targetType = targetType;
        this.guidSerializer = guidSerializer;
    }

    public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, StronglyTypedId<Guid> value)
    {
        guidSerializer.Serialize(context, args, value.Id);
    }

    public override StronglyTypedId<Guid> Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
    {
        var guid = guidSerializer.Deserialize(context, args);
        var idType = Activator.CreateInstance(targetType, new object[] { guid });
        return (idType as StronglyTypedId<Guid>)!;
    }
}

下面用於插入新文檔的代碼有效。

MongoClient dbClient = new MongoClient("mongodb://localhost:27017");
IMongoCollection<TestModel> collection = dbClient.GetDatabase("test").GetCollection<TestModel>("testmodel");

TestModel model = new TestModel(new TestModelId(Guid.NewGuid()), "test", "test");
collection.InsertOne(model);

但是使用Find讀取會引發異常: System.InvalidOperationException: 'The operands for operator 'Equal' do not match the parameters of method 'op_Equality'.'

TestModel found = collection.Find(x => x.Id == model.Id).FirstOrDefault();

我嘗試使用Equals代替,像這樣

TestModel found = collection.Find(x => x.Id.Equals(model.Id)).FirstOrDefault();

但這引發了另一個異常: System.ArgumentException: 'Method 'Boolean Equals(WebApplication2.Controllers.TestModelId)' declared on type 'WebApplication2.Controllers.TestModelId' cannot be called with instance of type 'WebApplication2.Controllers.StronglyTypedId`1[System.Guid]''

我不確定那里發生了什么,類型定義很清楚,但由於某種原因似乎類型不匹配? 我試圖用谷歌搜索任何解決方案,但找不到任何東西。

我沒有找到導致異常的原因,但我找到了解決方法:

var filter = Builders<TestModel>.Filter.Eq("_id", model.Id.Id);
TestModel found = collection.Find(filter).FirstOrDefault();

暫無
暫無

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

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