Я также реализовал нечто подобное для структуры Point3D.Как сказал cdmdotnet, вы в основном хотите реализовать и IUserType, который будет упаковывать / распаковывать компоненты в одну строку с помощью методов NullSafeSet / NullSafeGet.
Возможно, вам также потребуется реализовать метод Equals (), который немного неуловим,Причину лучше всего иллюстрирует пример:
Product p = session.Load(...);
p.Features.Add("extra feature");
session.Save(p);
Дело в том, что NHibernate при гидратации сохраняет ссылку на p.Features и сравнивает ее со значением p.Features по запросу на сохранение.Для неизменяемых типов свойств это нормально, но в приведенном выше примере эти ссылки идентичны, поэтому эффективное сравнение равно
var x = p.Features;
var changed = Equals(x, x);
Очевидно, стандартная реализация этого всегда будет возвращать false.
Как с этим бороться?Я понятия не имею, что такое лучший метод, но решения следующие:
Сделать IUserType.Equals (объект x, объект y) всегда возвращать false.Это заставит пересозданную упакованную строку и вызов базы данных каждый раз при сохранении Продукта, независимо от того, был ли Продукт семантически изменен или нет.Является ли это проблемой, зависит от любого количества факторов (размер / количество объектов Feature, сохраняются ли объекты Product, если они не были изменены, сколько у вас объектов Product и т. Д.).
Сделать функции IList и реализовать ChangeAwareList<T> : IList<T>
, который может отслеживать изменения (или сохранять копию своего оригинала) в курсе.Реализуйте IUserType.Equals (объект x, объект y), чтобы проверить, являются ли значения x / y ChangeAwareList, и реализуйте необходимую логику, чтобы увидеть, действительно ли список изменился.Это решение, которое я использовал в конце.
Возможно, вы могли бы повторно использовать код типа NHibernate GenericListType.В то время, когда я реализовывал предыдущее решение, у меня не было достаточно опыта, чтобы попробовать это.
Если у вас есть опыт работы с NHibernate, надеюсь, это поможет вам начать работу,Если нет, дайте мне знать, и я постараюсь составить более подробное решение.