12

在数据库中,我已经存储了数百个文档。现在系统架构发生了变化,并且(除其他外)模型被迁移到不同的命名空间(在不同的程序集中)。

下面显示了示例文档的元数据:

在此处输入图像描述

和我用来获取此类文档的代码:

var configuration = documentSession.Load<One.Social.Core.Entities.Setting>("Setting");

抛出铸造异常:

[InvalidCastException: Unable to cast object of type 'One.QA.Core.Entities.Setting' to type 'One.Social.Core.Entities.Setting'.]

更新:

类似的错误,但来自 NewtonsoftJson 上升,而我在文档中收集了指定类型,现在已更改。

在数据库中,我有问题文档,其中包含答案列表:

在此处输入图像描述

在代码中,类型如下所示:

namespace One.Social.Ask.Web.Models
{
    public class Question
    {        
        public string Content { get; set; }
        public IList<One.Social.Ask.Web.Models.Answer> Answers { get; set; }        
    }
}

答案命名空间已更改。另外,现在它是从 IList<> 派生的,没有 ICollection<>。我现在不需要$type元数据,它应该是:

在此处输入图像描述.

虽然它现在是一个列表,但由于旧$type信息而出现错误:

Newtonsoft.Json.JsonSerializationException: Error resolving type specified in JSON 'System.Collections.ObjectModel.Collection`1[[One.QA.Core.Entities.Answer, One.QA.Core]], mscorlib'. ---> Newtonsoft.Json.JsonSerializationException: Could not find type 'System.Collections.ObjectModel.Collection`1[[One.QA.Core.Entities.Answer, One.QA.Core]]' in assembly 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.

迁移所有文档以反映当前类型名称的最佳方法是什么?有没有内置机制?

顺便说一句:我正在使用 RavenDB - Build #960

4

4 回答 4

4

我遇到了同样的问题,最终这样做了:

Advanced.DatabaseCommands.UpdateByIndex(
    "Raven/DocumentsByEntityName",
        new IndexQuery {Query = "Tag:Album"},
        new []{ new PatchRequest() { 
            Type = PatchCommandType.Modify, 
            Name = "@metadata", 
            Nested= new []{ 
                new PatchRequest{
                    Name= "Raven-Clr-Type",
                    Type = PatchCommandType.Set,
                    Value = "Core.Model.Album, Core" }}}},
        false);
于 2014-02-20T22:25:30.450 回答
3

Jarek,问题的原因是你有两种类型。如果您删除 QA 类型,它将正常工作。或者,您可以按照 Wyatt 的建议进行操作并强制执行此操作。

于 2012-06-27T19:45:42.970 回答
2

您需要直接修补 ravendb 文档,而不是尝试反序列化它们。我自己从来不需要这样做,但我认为魔法是使用 IDocumentSession.Advanced.DatabaseCommands 中的方法完成的,尤其是Patch 方法

我真的没有什么可以测试的,但我认为代码应该如下所示:

//s is your document session
var toUpdate = s.Advanced.DatabaseCommands.StartsWith("Setting", 0, 128);
foreach (var d in toUpdate)
{
    var p = new PatchRequest();
    p.AllPositions = true;
    p.Type = PatchCommandType.Modify;
    d.Metadata["Raven-Clr-Type"] = "MyNewType";
    p.Value = d.ToJson();
    s.Advanced.DatabaseCommands.Patch(d.Key, new []{p});
}
// push forward and repeat for all items in collection

还有一种方法可以在不遍历集合的情况下执行此操作,但我不确定如何正确实现。

于 2012-06-27T11:13:49.383 回答
0

我在重命名后遇到了完全相同的问题casting exception。正如前面的答案所建议的,我最终根据这个片段修补了我的所有文档。

我们需要更新两个字段:Raven-Entity-NameRaven-Clr-Type

例子

重命名MyTypeMyNewType,将命名空间从 更新My.Namespace.MyTypeMy.New.Namespace.MyNewType

Raven-Entity-Name需要从 更改MyTypesMyNewTypes。为什么是复数?“约定优于配置”方法,如此处所述

Raven-Clr-Type需要从 更新My.Namespace.MyTypeMy.New.Namespace.MyNewType

代码

public static void PatchMetadata()
        {
            var operation = session.Advanced.DocumentStore.DatabaseCommands
            .UpdateByIndex(
                // You can check your index name in the Studio Under INDEXES.
                    "Raven/DocumentsByEntityName",
                //  query that will be performed
                    new IndexQuery
                    {
                        // A collection in RavenDB is a set of documents with the same tag. 
                        // The tag is defined in Raven-Entity-Name.
                        Query = "Tag:MyTypes"
                    }, new[]
                                {
                                    new PatchRequest
                                        {
                                            Type = PatchCommandType.Modify,
                                            Name = "@metadata",
                                            Nested = new[]
                                                {
                                                    new PatchRequest
                                                        {
                                                            Type = PatchCommandType.Set,
                                                            Name = "Raven-Entity-Name",
                                                            Value = new RavenJValue("MyNewTypes")
                                                        }
                                                        ,
                                                    new PatchRequest
                                                        {
                                                            Type = PatchCommandType.Set,
                                                            Name = "Raven-Clr-Type",
                                                            Value = new RavenJValue("My.New.Namespace.MyNewType, RavenDbPatching")
                                                        }
                                                }
                                        }
                                },
                    new BulkOperationOptions() { AllowStale = true }
            );
        }
于 2016-05-08T23:39:00.353 回答