gpt4 book ai didi

c# - MongoDB C# 驱动程序 - 将集合序列化为接口(interface)

转载 作者:行者123 更新时间:2023-12-03 23:53:54 24 4
gpt4 key购买 nike

由于工作环境的限制,我在 MongoDB 中实现了一个粗略的事件源存储。我正在尝试获取 IClientEvents 的列表像这样来自Mongo:

 var events = await _db.GetCollection<IClientEvent>("ClientEvents").FindAsync(c => c.ClientId == clientId);

运行上述存储库方法时出现以下异常:
Message: System.InvalidOperationException : {document}.ClientId is not supported.
IClientEvent接口(interface)定义为:
public interface IClientEvent
{
Guid Id { get; set; }
long TimeStamp { get; set; }
Guid ClientId { get; set; }
}

public class ClientChangedEvent : IClientEvent
{
public Guid Id { get; set; }
public long TimeStamp { get; set; }
public Guid ClientId { get; set; }

public IEnumerable<Change> Changes;
// ... other properties for the event
}

将有许多不同的事件类型存储到一个集合中,所有这些都将实现 IClientEvent .我只想在一次调用中获取 clientId 发生在客户端上的所有事件.

我已经注册了 IClientEvent 的所有具体实现。甚至添加了一个自定义鉴别器:
        var clientEventsDiscriminator = new ClientEventsMongoDiscriminatorConvention();
BsonSerializer.RegisterDiscriminatorConvention(typeof(IClientEvent),clientEventsDiscriminator);
BsonClassMap.RegisterClassMap<ClientChangedEvent>();
BsonSerializer.RegisterDiscriminatorConvention(typeof(ClientChangedEvent), clientEventsDiscriminator);

我什至尝试注册 ImpliedImplementationInterfaceSerializerthis SO post 中所述但是当我注册我已经为 IClientEvent 注册序列化程序的第二个具体实现时,它会引发异常.

不知道从这里去哪里。任何帮助是极大的赞赏!

-- 编辑更多代码:

这是完整的注册码:
        var clientEventsDiscriminator = new ClientEventsMongoDiscriminatorConvention();
BsonSerializer.RegisterDiscriminatorConvention(typeof(IClientEvent),clientEventsDiscriminator);

clientEventsDiscriminator.AddEventType<ClientChangedEvent>();
BsonClassMap.RegisterClassMap<ClientChangedEvent>();
BsonSerializer.RegisterDiscriminatorConvention(typeof(ClientChangedEvent), clientEventsDiscriminator);

clientEventsDiscriminator.AddEventType<ClientAddedEvent>();
BsonClassMap.RegisterClassMap<ClientAddedEvent>();
BsonSerializer.RegisterDiscriminatorConvention(typeof(ClientAddedEvent), clientEventsDiscriminator);

这是鉴别器:
    public class ClientEventsMongoDiscriminatorConvention : IDiscriminatorConvention
{
private Dictionary<string, Type> _eventTypes = new Dictionary<string, Type>();

public string ElementName => "_eventType";

public BsonValue GetDiscriminator(Type nominalType, Type actualType)
{
return GetDiscriminatorValueForEventType(actualType);
}

public Type GetActualType(IBsonReader bsonReader, Type nominalType)
{
var bookmark = bsonReader.GetBookmark();
bsonReader.ReadStartDocument();
if (!bsonReader.FindElement(ElementName))
{
throw new InvalidCastException($"Unable to find property '{ElementName}' in document. Cannot map to an EventType.");
}

var value = bsonReader.ReadString();
bsonReader.ReturnToBookmark(bookmark);

if (_eventTypes.TryGetValue(value, out var type))
{
return type;
}

throw new InvalidCastException($"The type '{value}' has not been registered with the '{nameof(ClientEventsMongoDiscriminatorConvention)}'.");
}

private string GetDiscriminatorValueForEventType(Type type)
{
var indexOfEventWord = type.Name.IndexOf("Event");
if (indexOfEventWord == -1)
{
return type.Name;
}
return type.Name.Substring(0, indexOfEventWord);
}

public void AddEventType<T>()
{
var discriminatorName = GetDiscriminatorValueForEventType(typeof(T));
_eventTypes.TryAdd(discriminatorName, typeof(T));
}
}

运行代码时,它似乎从未命中 GetActualType判别器的方法。

最佳答案

我设法通过简单地更改 IClientEvent 让它工作。从接口(interface)到抽象类。

关于c# - MongoDB C# 驱动程序 - 将集合序列化为接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52864459/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com