Zaimplementowałam również coś podobnego do struktury Point3D. Jako że cdmdotnet powiedział, że zasadniczo chcesz zaimplementować i IUserType, który spakie/rozpakuje funkcje w jeden ciąg za pomocą metod NullSafeSet/NullSafeGet.
Może być również konieczne zastosowanie metody Equals(), która jest nieco subtelna. Powodem, najlepiej ilustruje przykład:
Product p = session.Load(...);
p.Features.Add("extra feature");
session.Save(p);
Chodzi o to, NHibernate po sklepach hydratacji odniesienie do p.Features i porównuje ją z wartością p.Features momencie żądania składowania. Dla niezmiennych typów własności to jest w porządku, ale w powyższym przykładzie, te odniesienia są identyczne, więc skuteczne porównanie jest
var x = p.Features;
var changed = Equals(x, x);
Oczywiście standardem realizacja będzie zawsze return false.
Jak należy sobie z tym poradzić? Nie mam pojęcia, co najlepsze praktyki jest, ale rozwiązania są:
Bądź IUserType.Equals (obiekt x, y obiekt) zawsze return false. Zmusi to do przebudowania spakowanego łańcucha i wywołania bazy danych za każdym razem, gdy Produkt zostanie zapisany, bez względu na to, czy Produkt został zmieniony semantycznie, czy też nie. To, czy jest to problem, zależy od wielu czynników (wielkość/liczba obiektów Feature, czy obiekty produktu są zapisywane, gdy nie są zmienione, ile obiektów produktu masz itp.).
Twórz funkcje IList i wdrażaj ChangeAwareList<T> : IList<T>
, który jest w stanie śledzić zmiany (lub zachować kopię oryginału). Zaimplementuj IUserType.Equals (obiekt x, obiekt y), aby sprawdzić, czy x/y to ChangeAwareList i wdrożyć niezbędną logikę, aby sprawdzić, czy lista naprawdę się zmieniła. To jest rozwiązanie, które podjąłem w końcu.
Być może można ponownie użyć kodu z typu NHibernate GenericListType. W tym czasie zaimplementowałem poprzednie rozwiązanie, nie miałem wystarczającego doświadczenia, aby się na to zdobyć.
Jeśli masz jakieś wcześniejsze doświadczenia z NHibernate, mam nadzieję, że powinno to pomóc Ci zacząć. Jeśli nie daj mi znać, a ja postaram się opracować bardziej szczegółowe rozwiązanie.
Podoba mi się twoje rozwiązanie, ale chciałbym zadać pytanie. Narażasz właściwość 'Features' jako' List' sugerującą, że można nią manipulować używając 'Add' i' Remove' itd. Czy twoja lista naprawdę to robi. Jeśli nie, dlaczego nie wystawić "IEnountable"? –
Bardzo dobry punkt - to by miało więcej sensu. Używałbym metod pomocniczych do dodawania i usuwania. – DanB
@DanB, przepraszam za wykopanie starego posta: Stwierdzasz, że nadal przechowujesz kolekcję wyliczeń, ale nie jest dla mnie jasne, skąd bierzesz tę kolekcję do tego rozwiązania. Tylko dla odniesienia, możesz sprawdzić ten post, aby zobaczyć co robię: http://stackoverflow.com/questions/14288249/want-to-save-selected-ie-more-than-1-enums- is- string- z-nhibernate – REMESQ