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; }        
    }
}

Answers名前空間が変更されました。さらに、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を使用しています-ビルド#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タイプを削除すると、正常に機能します。または、ワイアットが提案したように実行して、これを強制することもできます。

于 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以前の回答でアドバイスしたように、私はこのスニペットに基づいてすべてのドキュメントにパッチを適用することになりました。

2つのフィールドを更新する必要があります:Raven-Entity-NameRaven-Clr-Type

に名前を変更MyTypeし、名前空間をからにMyNewType更新します。My.Namespace.MyTypeMy.New.Namespace.MyNewType

Raven-Entity-Nameからに変更する必要がありMyTypesますMyNewTypes。なぜ複数形なのか?ここで説明する「設定より規約」アプローチ。

Raven-Clr-Typeからに更新する必要がありMy.Namespace.MyTypeますMy.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 に答える