Хорошо, проблема здесь заключается в том, что использование десериализатора Json.NET в обычном режиме по существу создает новый объект - этот объект затем сохраняется в NHibernate. Конечным результатом является сохранение записи в базе данных, как и всех дочерних объектов, которые существуют в новой коллекции дочерних объектов - однако удаленные дочерние объекты являются осиротевшими, поскольку они не удаляются непосредственно из сохраняемого объекта NHibernate с помощью .Remove .clear.
Решение состоит из двух частей. Во-первых, мы должны использовать CustomCreationConverter
в Json.NET для передачи экземпляра существующего объекта, над которым нужно работать (слияние).
public static T Deserialize<T>(T existingObject, string json)
{
return JsonConvert.DeserializeObject<T>(json, new ObjectConverter<T>(existingObject));
}
public class ObjectConverter<T> : CustomCreationConverter<T>
{
public T ExistingObject { get; set; }
public ObjectConverter(T existingObject)
{
ExistingObject = existingObject;
}
public override T Create(Type objectType)
{
return ExistingObject;
}
}
Однако это само по себе не сработает, поскольку дочерние коллекции выходящих объектов будут добавлены к дочерними элементами в коллекции json. Исправьте это, и для того, чтобы NHibernate знал, что делать при получении результирующего объекта, нам нужно сделать небольшой взлом Json.NET.
Json.Net> Сериализация> JsonSerializerInternalReader.cs
private object PopulateList(IWrappedCollection wrappedList, JsonReader reader, string reference, JsonArrayContract contract)
{
// Edit // Clear the collection
wrappedList.Clear();
После перекомпиляции и повторного добавления DLL - это работает - потомки, которые удалены в javascript, наконец, удаляются и из БД.