płynne mapowanie relacji NHibernate-many-to-many na tej samej jednostce
Mam problem starając się odwzorować wiele do wielu relacji, gdzie obie strony relacji odnoszą się do tej samej istoty. Używam Fluent NHibernate i NH3.1.
Zasadniczo scenariusz jest taki - mam kategorię, która może mieć wielu rodziców. Tak więc kategoria ma wiele innych kategorii jako rodzice, a także wiele innych kategorii jako Dzieci.
HasManyToMany(x => x.ParentCategories).AsBag().Table("parentcategorychildren").ParentKeyColumn("ChildID").ChildKeyColumn("ParentID").Cascade.SaveUpdate();
HasManyToMany(x => x.ChildrenCategories).AsBag().Table("parentcategorychildren").ParentKeyColumn("ParentID").ChildKeyColumn("ChildID").Inverse();
Jednak, kiedy próbuję zbudować fabrykę, dostaję następujący błąd:
Kategoria relacji.Dziecikategorie do kategorii.ChildrenCategories ma odwrotność określoną po obu stronach. Usuń odwrotność z jednej strony Związku.
To, co uważam za dziwne, to dlaczego wymienia " kategorię.Dziecikategorie " do kategorii.Kategorie dzieci, w przeciwieństwie do kategorii rodziców?
Każda pomoc będzie bardzo mile widziana !Stworzyłem nagrodę za to, bo to jest dla mnie wystarczająco ważne. Proszę, nie jestem zainteresowany. w "nie możesz tego zrobić" jako odpowiedź.
3 answers
Jest to najprawdopodobniej błąd FNH i najprawdopodobniej został już naprawiony w najnowszym kodzie źródłowym FNH . Nie ma problemu przy użyciu FNH1. 0 i NH2. 1. Analogiczne odwzorowanie HBM działa dobrze w FNH1. 2 i NH3. 1:
<bag name="ParentCategories" cascade="all" table="parentcategorychildren">
<key column="ChildID" />
<many-to-many column="ParentID" class="Category" />
</bag>
<bag name="ChildrenCategories" inverse="true" table="parentcategorychildren">
<key column="ParentID" />
<many-to-many column="ChildID" class="Category" />
</bag>
Edytuj: Po kopaniu w kodzie źródłowym FNH znalazłem obejście. Załóżmy, że Twoja konfiguracja wygląda tak:
.Mappings(m => {
m.FluentMappings.AddFromAssemblyOf<Category>();
})
Pechowy kod może być tłumiony przez tę konfigurację:
.Mappings(m => {
var persistenceModel = new PersistenceModel();
persistenceModel.AddMappingsFromAssembly(typeof(Category).Assembly);
persistenceModel.ValidationEnabled = false; // this makes the trick
m.UsePersistenceModel(persistenceModel);
})
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-12 05:09:20
Jest to problem z walidacją/parowaniem relacji Fluent NHibernate 2.1. FNH paruje relacje , a następnie potwierdza, że tylko jedna strona relacji ma .Inverse()
określone. Ponieważ oba odniesienia (rodzic/dziecko) są do tej samej klasy, oba pasują do kandydatów podczas parowania. W takim przypadku FNH pasuje do podobieństwa nazw. W konsekwencji, każdy z nich jest sparowany ze sobą, a nie ze sobą. Więc umieszczając .Inverse()
na którymś z uruchamia walidację (obie strony pary są tą samą relacją, która jest odwrotna).
Powinno być możliwe skorygowanie tego za pomocą metody OverrideBiDirectionalManyToManyPairing()
w programie FluentMappingsContainer. Teoretycznie, to pozwoli Ci wyraźnie powiązać relacje między dzieckiem i rodzicem. Jednak w FNH 2.1 jest błąd, i override callback nigdy nie jest wywoływany. (wartość wywołania zwrotnego jest przechwytywana, zanim może być ustawiona metodą ).
Jako obejście, można wyłączyć wszystkie Walidacja w FNH. Istnieją tylko dwie walidacje . Po pierwsze, że obie strony Związku nie mają .Inverse()
. Po drugie, że identyfikator jest mapowany na każdym obiekcie. Najczystszym sposobem, jaki znalazłem, aby wyłączyć walidację, jest:
.Mappings(m => {
var persistenceModel = new PersistenceModel() { ValidationEnabled = false };
m.UsePersistenceModel(persistenceModel)
.FluentMappings.AddFromAssemblyOf<Category>();
})
To podejście pozwala wyłączyć walidację, ale nadal używać pełnej ekspresji konfiguracji FluentMappings
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-12 20:21:58
Tak wydawało mi się, że najprawdopodobniej był to błąd w FNH, ponieważ próbowałem go bezpośrednio z NHibernate bez używania Fluent NH i zadziałało. Jednak ponieważ już skonfigurowałem system za pomocą FNH, nie mogłem po prostu powrócić do tego, że go nie używałem.
To, co zrobiłem, to stworzyłem siebie jako "klasę w środku" dla relacji wielu do wielu, która normalnie jest generowana automatycznie. Stworzyłem stronę ContentPage_ChildLink
, która łączyła kategorie Parents
i Children
. To pozwoliło mi pracować z FNH i obejść problem:)
Zasadniczo to ContentPage_ChildLink
będzie miało dwa pola, ChildID
i ParentID
. Mógłbym wtedy ustawić "odwrotne" relacje osobno, bez żadnego problemu.
Problem z FNH wydaje się być wtedy, gdy masz wiele do wielu relacji, które obie strony są tej samej klasy, jedyny przypadek mogę myśleć jest struktura hierarchii, która pozwala na wielu rodziców.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-16 09:32:32