nHibernate Cascade AllDeleteOrphan: Почему NH удаляет каждый элемент коллекции отдельно - PullRequest
0 голосов
/ 31 августа 2011

Когда я очищаю дочернюю коллекцию, как это

table.Indizes.Clear();
session.Flush();

, тогда NH генерирует SQL удаления для каждого элемента, который был в коллекции:

DELETE FROM x_inddef WHERE ind_name = 'IDX_ADRKONZ_CODE'AND tbl_name =' ADRESSE 'УДАЛИТЬ ИЗ x_inddef WHERE ind_name =' IDX_ADRKUND_EXT 'И tbl_name =' ADRESSE '

...

Почему он не генерирует подобное утверждение?

DELETE FROM x_inddef WHERE tbl_name = 'ADRESSE'

Что-то не так с моими сопоставлениями или это просто нормальное поведение?

Упрощенный код с быстрым сопоставлением:

public class Table
{
    public virtual string Name {get;set;
    public virtual IList<Index> Indizes { get; set; }
}

public class TableOverride : IAutoMappingOverride<Table>
{
    public void Override(AutoMapping<Table> mapping)
    {
        mapping.Table("x_tables");
        mapping.Id(x => x.Name, "tbl_name");
        mapping.HasMany(x => x.Indizes).KeyColumn("tbl_name").Inverse().Cascade.AllDeleteOrphan();
    }
}

public class Index
{
    public virtual string Name { get; set; }
    public virtual Table Table { get; set; }

    public override bool Equals(object obj)
    {
        //...
    }

    public override int GetHashCode()
    {
        //...
    }
}

public class IndexOverride : IAutoMappingOverride<Index>
{
    public void Override(AutoMapping<Index> mapping)
    {
        mapping.Table("x_inddef");
        mapping.CompositeId().
            KeyProperty(x => x.Name, "ind_name").
            KeyReference(x => x.Table, "tbl_name");
    }
}

Ответы [ 4 ]

3 голосов
/ 31 августа 2011

Вы должны включить опцию пакетного обновления с nhibernate

Прежде всего установите значение adonet.batch_size в конфигурации NHibernate на значение, большее нуля.

А затем пометьте каждую коллекцию hasMany .BatchSize(xxx)

mapping.HasMany(x => x.Indizes)
   .BatchSize(25)
   .KeyColumn("tbl_name")
   .Inverse()
   .Cascade.AllDeleteOrphan();

Думаю, это должно помочь

1 голос
/ 31 августа 2011

Удаление одним выстрелом не работает с обратным = true.Выделение нового экземпляра коллекции индекса с 0 элементами и разыменование старого вызывает исключение, поскольку Nhibernate ожидает управления коллекцией.Кажется, единственным выходом является использование hql.

Проверьте раздел 19.5.4 в документации - http://www.nhforge.org/doc/nh/en/index.html

0 голосов
/ 02 сентября 2011

Другое возможное решение - использовать HQL:

session.CreateQuery("DELETE Index i WHERE i.Table.Name = :tblName")
    .SetString( "tblName", "MyTable" )
    .ExecuteUpdate();
0 голосов
/ 31 августа 2011

All-delete-orphan означает, что ваша дочерняя коллекция будет удалена, если вы удалите родительский элемент.
означает - если вы удалите объект Table, будет выдано DELETE FROM x_inddef WHERE tbl_name =....
вызовет Clear()это просто сокращение для удаления всех объектов в коллекции, но сам объект Table остается неизменным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...