我刚刚完成了对我的应用程序的一轮重构,这导致我删除了一个不再需要的项目并将其类移动到另一个项目中。这样做的副作用是我的User
类存储在RavenDB中,它具有移动到新程序集的类型的集合属性。一旦我尝试查询User
类的会话,我就会收到Json
反序列化错误。 here触及了这个问题,但答案并没有解决我的问题。这是令人讨厌的财产:
{
"OAuthAccounts": {
"$type": "System.Collections.ObjectModel.Collection`1[
[Friendorsement.Contracts.Membership.IOAuthAccount,
Friendorsement.Contracts]], mscorlib",
"$values": []
},
}
OAuthAccounts
是User
的集合属性,用于在此处进行映射:
System.Collections.ObjectModel.Collection`1 [[Friendorsement.Contracts.Membership.IOAuthAccount,Friendorsement.Contracts]]
现在映射到这里:
System.Collections.ObjectModel.Collection`1 [[Friendorsement.Domain.Membership.IOAuthAccount,Friendorsement.Domain]]
Friendorsement.Contracts
不再存在。它的所有类型现在都在Friendorsement.Domain
我尝试使用store.DatabaseCommands.StartsWith("User", "", 0, 128)
,但没有返回任何内容。
我已经尝试过UpdateByIndex
,但没有达到目标:
store.DatabaseCommands.UpdateByIndex("Raven/DocumentsByEntityName",
new IndexQuery {Query = "Tag:Users"},
new[]
{
new PatchRequest { // unsure what to set here }
});
我正在使用Raven 2.0
答案 0 :(得分:2)
下面是一个简单的示例应用程序,它向您显示修补元数据。虽然你的例子有点不同,但这应该是一个很好的起点
namespace SO19941925
{
internal class Program
{
private static void Main(string[] args)
{
IDocumentStore store = new DocumentStore
{
Url = "http://localhost:8080",
DefaultDatabase = "SO19941925"
}.Initialize();
using (IDocumentSession session = store.OpenSession())
{
for (int i = 0; i < 10; i++)
{
session.Store(new User {Name = "User" + i});
}
session.SaveChanges();
}
using (IDocumentSession session = store.OpenSession())
{
List<User> users = session.Query<User>().Customize(x => x.WaitForNonStaleResultsAsOfNow()).ToList();
Console.WriteLine("{0} SO19941925.Users", users.Count);
}
Operation s = store.DatabaseCommands.UpdateByIndex("Raven/DocumentsByEntityName",
new IndexQuery {Query = "Tag:Users"},
new ScriptedPatchRequest
{
Script = @"this['@metadata']['Raven-Clr-Type'] = 'SO19941925.Models.User, SO19941925';"
}, true
);
s.WaitForCompletion();
using (IDocumentSession session = store.OpenSession())
{
List<Models.User> users =
session.Query<Models.User>().Customize(x => x.WaitForNonStaleResultsAsOfNow()).ToList();
Console.WriteLine("{0} SO19941925.Models.Users", users.Count);
}
Console.ReadLine();
}
}
internal class User
{
public string Name { get; set; }
}
}
namespace SO19941925.Models
{
internal class User
{
public string Name { get; set; }
}
}
更新:根据上面的初步答案,这里是实际解决OP问题的代码:
store.DatabaseCommands.UpdateByIndex("Raven/DocumentsByEntityName",
new IndexQuery {Query = "Tag:Users"},
new ScriptedPatchRequest
{
Script = @"this['OAuthAccounts']['$type'] =
'System.Collections.ObjectModel.Collection`1[
[Friendorsement.Domain.Membership.IFlexOAuthAccount,
Friendorsement.Domain]], mscorlib';",
}, true
);
答案 1 :(得分:0)
以下是两种可能的解决方案:
选项1:根据项目所处的状态,例如,如果您仍在开发中,您可以轻松地从Raven Studio中删除RavenDB中的该集合,并重新创建所有这些用户文档。然后,所有新的User文档都应具有正确的类名和程序集,然后应正确反序列化。显然,如果你已经投入生产,这可能不是一个好的选择。
选项2:根据您拥有的用户文档的数量,您应该能够手动编辑每个用户文档以指定正确的C#类名称和程序集,以便正确地反序列化它们。同样,如果你有太多的对象需要手动修改,这可能不是一个好的选择;但是,如果只有少数几个,那么打开每一个都不应该太糟糕,请转到元数据选项卡并粘贴“Raven-Entity-Name”和“Raven-Clr-Type”的正确值。
答案 2 :(得分:0)
我最终这样做了:
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);