I write plugins that they themselves control their mapping into the database. Connection is solved easily, entities are saved, everything works as it should.

The question is simple - how to make plug-ins disconnected, if the data created in the database is ignored?

Now when accessing an entity for which the mapping is not loaded, the error falls:

NHibernate. persister, Object id, ISessionImplementor session)

And I would be more satisfied if he reacted as if the record was not at all in the database.

In addition to the above - a map in one tablet, all implementations of a specific interface, i.e. Table Per Class Hierarchy. As long as the calls are typed (specific class) or by id - everything is OK, when the entire label on the interface is simply requested - it falls on the non-merged ones.

    2 answers 2

    It seems that the standard means to ignore the discriminator will not work. You can try to use the filter on the mapping, like this:

     var cfg = new Configuration(); // здесь настраиваем конфигурацию, подключаем плагины // GetPluginsGuid возвращает GUID-ы всех подключенных плагинов IEnumerable<Guid> discriminators = GetPluginsGuid(); var mapping = cfg.GetClassMapping(typeof(IPluginInterface)); // поле-дискриминатор var discriminatorColumn = mapping.Discriminator.ColumnIterator.First().Text; mapping.Where = String.Format("{0} IN ('{1}')", discriminatorColumn, String.Join("','", discriminators)); // ... 

    After that, the query results will disappear lines with invalid values ​​of discriminators.

    Also, in order to avoid exceptions when accessing other entities with an invalid foreign key value, you need to set the attribute not-found="ignore" on the corresponding association:

     <many-to-one name="SomeAssociation" class="IPluginInterface" ... not-found="ignore"> 
    • The idea caught, always where available discriminators. It took off, thanks. Maybe you can tell how to handle NHibernate.ObjectNotFoundException: No row with the given identifier exists , which occurs when the link to the missing record? Or is it a hint that I have built the wrong model and need to do something with the model? - Monk
    • @Monk and this is what action happens? session.Get or Query simply return null. - kmv
    • Another entity is loaded, which has a link to the missing entity in the database. As a result, materialization simply falls: pastebin.com/XSY3TG4x - Monk
    • @Monk really, it turns out the broken value of the foreign key. Do you have an association ( many-to-one ) on the essence of plug-ins in this other entity? Then you need to put on it the attribute not-found="ignore" - kmv
    • In a fluent, I did it like this, and at least it doesn't roll in, but References(x => x.Login).Cascade.All().NotFound.Ignore(); - Monk

    Actually, thanks to the help of comrade kmv, I managed to sketch a working version.

    After loading mappings in ExposeConfiguration you can add filters.

      foreach (var source in config.ClassMappings.Where(m => m.Discriminator != null && m is RootClass)) { source.Where = string.Format("{0} in ('{1}')", source.Discriminator.ColumnIterator.Single().Text, string.Join("', '", source.SubclassIterator.Select(i => i.DiscriminatorValue))); } 

    The calculation is strictly on a simple discriminator, although judging by the API, they can be composite. Subclasses are already loaded, and therefore you can always add an explicit filter for them. The m.Discriminator != null and m is RootClass required, the first is for filtering by the field itself, the second is for determining that it is the root mapping. Subclasses can not filter the toli, toli no sense, I do not remember.

    If an entity holds a link to such an object, then for it you need to remember to add a blacklist to the NotFound event:

      References(x => x.Login).Cascade.All().NotFound.Ignore(); 

    Now it is necessary to take into account that even if the field is always filled, in such an implementation, null can also return from the database.