在数据库中,我已经存储了数百个文档。现在系统架构已经改变,并且(其中)模型被迁移到不同的命名空间(在不同的程序集中)。
下面显示了示例文档的元数据:
和我用来获取此类文档的代码:
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,我在dosument里面有指定类型的集合,现在已经改变了。
在数据库中我有问题文档,其中包含答案列表:
在代码中,类型如下:
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&lt;&gt;,没有ICollection&lt;&gt;。我现在不需要$type
meta,它应该是:
。
虽然它现在是一个列表,但由于旧的$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
答案 0 :(得分:3)
亚雷克, 问题的原因是你有这两种类型。 如果您删除QA类型,它将起作用。 或者,你可以像怀亚特所建议的那样强迫这一点。
答案 1 :(得分:3)
我遇到了同样的问题并最终做到了这一点:
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);
答案 2 :(得分:1)
您需要直接修补ravendb文档而不尝试反序列化它们。我自己从来没有这样做,但我认为使用IDocumentSession.Advanced.DatabaseCommands中的方法完成了魔术,特别是Patch method。
我真的没有什么可以测试的,但我认为代码应该是这样的:
//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
还有一种方法可以在不循环收集的情况下执行此操作,但我不确定如何正确实现。
答案 3 :(得分:0)
重命名后,我遇到了casting exception
完全相同的问题。
正如前面的答案所述,我最终根据this snippet修补了我的所有文件。
我们需要更新两个字段:Raven-Entity-Name
和Raven-Clr-Type
。
示例
将MyType
重命名为MyNewType
,将名称空间从My.Namespace.MyType
更新为My.New.Namespace.MyNewType
。
Raven-Entity-Name
需要从MyTypes
更改为MyNewTypes
。复数为何? &#34;约定优于配置&#34;方法,as explained here。
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 }
);
}