【问题标题】:Getting NServiceBus Subscriptions from RavenDB从 RavenDB 获取 NServiceBus 订阅
【发布时间】:2013-11-13 17:28:39
【问题描述】:

有没有人尝试(并成功)使用 Raven DB .Net 客户端从 RavenDB 获取订阅?

有一些 Json 序列化问题,当以下运行时,它会抛出一个

“将值“Subscriber.Messages.Events.MyEvent, Version=1.0.0.0”转换为类型“NServiceBus.Unicast.Subscriptions.MessageType”时出错。消息

代码很简单:

            var documentStore = new DocumentStore
            {
                Url = "http://localhost:8080/",
                DefaultDatabase = "publisher",
            };

            documentStore.Initialize();

            using (var session = documentStore.OpenSession())
            {

                return session.Query<NServiceBus.Unicast.Subscriptions.Raven.Subscription>("Raven/DocumentsByEntityName").ToArray();
            }

这绝对是检索工作的序列化问题。就像它使用下面的替代方法一样:

session.Advanced.LuceneQuery<Subscription>("Raven/DocumentsByEntityName").QueryResult.Results[0]

在 RaveDB 工作室中,我可以在发布者数据库中看到以下文档。

{
  "MessageType": "Subscriber.Messages.Events.MyEvent, Version=1.0.0.0",
  "Clients": [
    {
      "Queue": "samplesubscriber",
      "Machine": "myDesktopHere"
    }
  ]
}

将值“Subscriber.Messages.Events.MyEvent, Version=1.0.0.0”转换为类型“NServiceBus.Unicast.Subscriptions.MessageType”时出错。

有人知道序列化失败的原因吗?

我正在使用 NServiveBus.Host 4.2、Raven-DB 客户端 1.0.616 和 Newtonsoft.json 4.0.5。

顺便说一句,我已经使用 dotpeek 提取了类型并创建了本地版本。我从 NSB dll 创建了自己的订阅、MessageType、MessageTypeConvertor。然后我设法反序列化字符串没有问题。有什么想法吗?

编辑

根据建议,高级 Lucene 查询在检索结果方面做得很好。但随后反序列化失败。例如,搜索结果在第一行返回,但在 return 语句中无法反序列化。我从 NSB dll 中提取了 Subscription 类型的本地版本,并实现了类型转换器,再次从 NSB 库中提取,并使用那些代替 NServiceBus.Unicast.Subscriptions.Raven.Subscription 工作正常。不可避免地,这不是一个稳定的选择。

var searchResults = session.Advanced.LuceneQuery<NServiceBus.Unicast.Subscriptions.Raven.Subscription>("Raven/DocumentsByEntityName").WhereEquals("Tag", "Subscription").QueryResult.Results;

return searchResults.Select(subscriptionJsonObject => JsonConvert.DeserializeObject<NServiceBus.Unicast.Subscriptions.Raven.Subscription>(subscriptionJsonObject.ToString())).ToList(); 

还有什么想法吗?

【问题讨论】:

    标签: json.net ravendb nservicebus


    【解决方案1】:

    当您使用此表单查询时:

    session.Query<Entity>("IndexName")
    

    您要求从查询中返回该索引的 all 项,然后告诉 RavenDB 客户端将它们 all 反序列化为您指定的类型。

    通常,这很有效,因为将为您正在使用的类型构建一个特定的索引。例如,您通常会为特定目的构建自己的订阅索引,然后查询:

    session.Query<Subscription>("Subscriptions/ByWhatever")
    

    或者如果你从 C# 构建索引,你可能会喜欢这个语法来避免字符串:

    session.Query<Subscription, Subscriptions_ByWhatever>()
    

    您也可以让 Raven 自动为您构建索引:

    session.Query<Subscription>()
    

    由于您使用了内置的Raven/DocumentsByEntityName 索引,您将返回数据库中的所有文档,而不仅仅是那些订阅的文档。由于只有一些可以反序列化为 Subscription 类型,因此其他的因序列化错误而失败。

    如果您想继续使用该索引,则需要将其过滤为该类型的索引:

    session.Advanced.LuceneQuery<Subscription>("Raven/DocumentsByEntityName")
                    .WhereEquals("Tag", "Subscriptions")
    

    LuceneQuery 表单在这里更容易,因为您正在通过字符串名称过滤字段。

    您可以使用常规 LINQ 查询,但您必须创建一个包含 Tag 字段的类型,如下所示:

    class RDBENIndexEntry
    {
        public string Tag { get; set; }
    }
    
    ...
    
    session.Query<RDBENIndexEntry>("Raven/DocumentsByEntityName")
           .Where(x => x.Tag == "Subscriptions").OfType<Subscription>()
    

    【讨论】:

    • 感谢马特,不幸的是,这并不能解决问题。正如建议的那样,我使用高级查询撤回了结果。该位有效,但序列化后检索失败。我会用细节编辑原件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多