c# - nhibernate fluido-mapeo de relaciones muchos a muchos en la misma entidad
fluent-nhibernate many-to-many (3)
Es muy probable que este sea un error de FNH y que probablemente ya esté solucionado en el último código fuente de FNH. No hay ningún problema al usar FNH1.0 y NH2.1. El mapeo de HBM equivalente funciona bien en FNH1.2 y 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>
EDITAR: Después de excavar en el código fuente de FNH, encontré una solución. Digamos, su configuración se ve así:
.Mappings(m => {
m.FluentMappings.AddFromAssemblyOf<Category>();
})
El código desafortunado puede ser suprimido por esta configuración:
.Mappings(m => {
var persistenceModel = new PersistenceModel();
persistenceModel.AddMappingsFromAssembly(typeof(Category).Assembly);
persistenceModel.ValidationEnabled = false; // this makes the trick
m.UsePersistenceModel(persistenceModel);
})
Tengo un problema al tratar de trazar una relación de muchos a muchos, donde ambos lados de la relación hacen referencia a la misma entidad. Estoy usando Fluido NHibernate y NH3.1.
Básicamente, el escenario es el siguiente: tengo una categoría que puede tener varios padres. Por lo tanto, una categoría tiene varias otras categorías como padres, así como varias otras categorías como sus hijos.
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();
Sin embargo, cuando intento construir la fábrica, aparece el siguiente error:
La relación Category.ChildrenCategories con Category.ChildrenCategories tiene Inverse especificado en ambos lados. Retire Inverso de un lado de la relación.
Lo que me parece extraño es por qué menciona ''Category.ChildrenCategories'' a Category.ChildrenCategories, en lugar de ParentCategories?
Cualquier ayuda sería muy apreciada!
Acabo de crear una recompensa por esto, porque es lo suficientemente importante para mí. Por favor, no estoy interesado en "no puedes hacer esto" como respuesta.
Este es un problema con la validación / emparejamiento de relaciones de Fluent NHibernate 2.1. FNH empareja relaciones y luego valida que solo un lado de la relación tiene especificado .Inverse()
. Debido a que ambas referencias (padre / hijo) pertenecen a la misma clase, ambas son candidatas al emparejarse. En ese caso, FNH coincide con la similitud de nombre . En consecuencia, cada uno se empareja con ellos mismos en lugar de uno con el otro. Entonces, al colocar .Inverse()
en uno de los dos se activa la validación (ambos lados del par son la misma relación que es inversa).
Debería ser posible corregir esto utilizando el método OverrideBiDirectionalManyToManyPairing()
en el FluentMappingsContainer. En teoría, eso le permitiría emparejar explícitamente las relaciones padre e hijo. Sin embargo, en FNH 2.1 hay un error, y la devolución de llamada de anulación nunca se llama. ( El valor de devolución de llamada se captura antes de que se pueda establecer mediante el método ).
Como solución, puede deshabilitar toda la validación en FNH. Sólo hay github.com/jagregory/fluent-nhibernate/blob/release-1.2/src/… . Primero, que ambos lados de una relación no tienen .Inverse()
. En segundo lugar, que se asigna una identificación en cada entidad. La forma más limpia que he encontrado para deshabilitar la validación es:
.Mappings(m => {
var persistenceModel = new PersistenceModel() { ValidationEnabled = false };
m.UsePersistenceModel(persistenceModel)
.FluentMappings.AddFromAssemblyOf<Category>();
})
Este enfoque le permite deshabilitar la validación pero seguir utilizando la expresividad completa de la configuración de FluentMappings
.
Sí, me pareció que probablemente era un error en FNH, ya que lo probé directamente con NHibernate sin usar Fluent NH y funcionó. Sin embargo, como ya había configurado un sistema con FNH, no podía volver a no usarlo.
Lo que hice fue crearme como un ''clase en el medio'' para la relación de muchos a muchos, que normalmente se genera automáticamente. ContentPage_ChildLink
una página ContentPage_ChildLink
, que vinculaba las categorías Parents
e Children
. Esto me permitió trabajar con FNH y solucionar el problema :)
Básicamente, este ContentPage_ChildLink
tendría dos campos, ChildID
y ParentID
. Entonces podría establecer las relaciones ''Inversas'' por separado, sin ningún problema.
El problema con FNH parecía ser cuando tienes una relación de muchos a muchos, en la que ambos lados son de la misma clase, el único caso que se me ocurre es una estructura jerárquica que permite múltiples padres.