我在RavenDB中序列化/反序列化时遇到了一些麻烦。我在存储数据方面没有问题,但在查询文档时遇到问题。
我有一个相当复杂的Account类,它是从Entity Framework v4.3 POCO生成器生成的:
[Serializable]
public class Account
{
public Guid Id { get; set; }
public string Name { get; set; }
public DateTime CreatedDate { get; set; }
public List<Product> ProductsOwned { get; set; }
public bool IsActive { get; set; }
public Nullable<DateTime> DOB { get; set; }
public Address HomeAddress { get; set; }
// shortened for brevity
}
当我查询我的对象并将它们作为List返回时,我得到一个.NET Reflection Error“对象与目标类型不匹配”。
var results = (from account in mySession.Query<Account>()
where account.IsActive == true
select account).ToList<Account>(); // this is where error occurs
我认为这可能是因为我保存了其他嵌套类和nullables也被序列化了,但我发现我可以像这样创建一个名为AccountWrapper的“wrappper”类:
public class AccountWrapper
{
public Guid Id { get; set; }
public string SerializedText { get; set; }
}
在这里,我将手动使用JSON.NET(是的,与RavenDB Buid 960一样的.dll)填充SerializedText字段,然后将其存储到RavenDB。这个过程会起作用!我将从RavenDB中获取AccountWrapper对象,然后手动反序列化SerializedText的内容。这让我相信默认(反)序列化过程可能存在问题。
所以我的问题是,当我存储/加载文档时,有没有办法在RavenDB上手动覆盖Serialize / Deserialize功能?如果是这样,有人能告诉我一个如何这样做的干净的例子吗?然后我可以使用标准JsonConverter.Serialize()
作为JSON.NET
显然使用AccountWrapper是一个坏主意,因为我无法索引我需要查询的“真实”数据。
(下面的完整堆栈跟踪例外)
System.Reflection.TargetException: Object does not match target type. at System.Reflection.RuntimeMethodInfo.CheckConsistency(Object target)
at System.Reflection.RuntimeMethodInfo.InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
at Newtonsoft.Json.Serialization.JsonContract.InvokeOnDeserialized(Object o, StreamingContext context) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\Serialization\JsonContract.cs:line 172
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateList(IWrappedCollection wrappedList, JsonReader reader, String reference, JsonArrayContract contract) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalReader.cs:line 774
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.<>c__DisplayClass1.<CreateAndPopulateList>b__0(IList l, Boolean isTemporaryListReference) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalReader.cs:line 744
at Newtonsoft.Json.Utilities.CollectionUtils.CreateAndPopulateList(Type listType, Action`2 populateList) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\Utilities\CollectionUtils.cs:line 233
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateAndPopulateList(JsonReader reader, String reference, JsonArrayContract contract) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalReader.cs:line 732
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue, String reference) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalReader.cs:line 495
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalReader.cs:line 238
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueProperty(JsonReader reader, JsonProperty property, JsonConverter propertyConverter, Object target, Boolean gottenCurrentValue, Object currentValue) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalReader.cs:line 213
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonReader reader, Object target) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalReader.cs:line 617
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, String id) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalReader.cs:line 1203
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateAndPopulateObject(JsonReader reader, JsonObjectContract contract, String id) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalReader.cs:line 956
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalReader.cs:line 433
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalReader.cs:line 236
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueNonProperty(JsonReader reader, Type objectType, JsonContract contract, JsonConverter converter) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalReader.cs:line 221
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalReader.cs:line 117
at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\JsonSerializer.cs:line 421
at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\JsonSerializer.cs:line 413
at Raven.Client.Connection.JsonExtensions.Deserialize(RavenJObject self, Type type, DocumentConvention convention) in c:\Builds\RavenDB-Stable\Raven.Client.Lightweight\Connection\JsonExtensions.cs:line 30
at Raven.Client.Document.InMemoryDocumentSessionOperations.ConvertToEntity[T](String id, RavenJObject documentFound, RavenJObject metadata) in c:\Builds\RavenDB-Stable\Raven.Client.Lightweight\Document\InMemoryDocumentSessionOperations.cs:line 416
at Raven.Client.Document.InMemoryDocumentSessionOperations.TrackEntity[T](String key, RavenJObject document, RavenJObject metadata) in c:\Builds\RavenDB-Stable\Raven.Client.Lightweight\Document\InMemoryDocumentSessionOperations.cs:line 340
at Raven.Client.Document.SessionOperations.QueryOperation.Deserialize[T](RavenJObject result) in c:\Builds\RavenDB-Stable\Raven.Client.Lightweight\Document\SessionOperations\QueryOperation.cs:line 130
at System.Linq.Enumerable.WhereSelectListIterator`2.MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at Raven.Client.Document.SessionOperations.QueryOperation.Complete[T]() in c:\Builds\RavenDB-Stable\Raven.Client.Lightweight\Document\SessionOperations\QueryOperation.cs:line 114
at Raven.Client.Document.AbstractDocumentQuery`2.GetEnumerator() in c:\Builds\RavenDB-Stable\Raven.Client.Lightweight\Document\AbstractDocumentQuery.cs:line 616
at Raven.Client.Linq.RavenQueryInspector`1.GetEnumerator() in c:\Builds\RavenDB-Stable\Raven.Client.Lightweight\Linq\RavenQueryInspector.cs:line 98
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
答案 0 :(得分:3)
这应该有效,你能否提供更多细节,失败的测试用例会很棒。
无论如何,您可以使用以下方式自定义:
documentStore.Conventions.CustomizeSerializer