Как заставить NHibernate не обновлять все объекты в коллекции - PullRequest
3 голосов
/ 22 февраля 2010

Как заставить NHibernate не генерировать UPDATE для каждого элемента в коллекции, если я изменяю только один элемент из этой коллекции. Вот оно:

internal class Master
{
    private int _id;

    public string Name { get; set; }
    public ISet<Slave> Slaves { get; set; }

    public Master()
    {
        Slaves = new HashedSet<Slave>();
    }
}

internal class Slave
{
    private int _id;

    public string Name { get; set; }
    public Master Master { get; set; }
}

Отображения:

<class name="nHibernateTutorials.Slave, nHibernateTutorials" lazy="false">
    <id access="field" name="_id" column="id">
        <generator class="native"/>
    </id>
    <property access="property" name="Name" column="name"/>
    <many-to-one access="property" name="Master" column="master"/>
</class>

<class name="nHibernateTutorials.Master, nHibernateTutorials" lazy="false">
    <id access="field" name="_id" column="id">
        <generator class="native"/>
    </id>
    <property access="property" name="Name" column="name"/>
    <set access="property" name="Slaves" cascade="save-update">
        <key column="master"/>
        <one-to-many class="nHibernateTutorials.Slave, nHibernateTutorials"/>
    </set>
</class>

Код, который обновляет элемент коллекции:

Master m = new Master {Name = "Kenny"};

Slave s1 = new Slave { Name = "Cartman", Master = m};
m.Slaves.Add(s1);
Slave s2 = new Slave {Name = "Kyle", Master = m};
m.Slaves.Add(s2);
Slave s3 = new Slave {Name = "Stan", Master = m};
m.Slaves.Add(s3);

DbManager.SaveObject(m);

s1.Name = "Daisy";
DbManager.SaveObject(m);

Код в DbManager.SaveObject просто открывает новый сеанс и использует SaveOrUpdate для обновления объекта.

Если я изменяю один из элементов из основной коллекции Slaves и затем пытаюсь обновить master, NHibernate генерирует SQL для обновления всех элементов в коллекции Slaves. Но мне нужно обновить только один элемент.

Спасибо.

Ответы [ 3 ]

1 голос
/ 22 февраля 2010

Вы, вероятно, видите лишние обновления "многие к одному". Когда вы отображаете коллекции «один ко многим», вы должны выбрать, какая сторона является владельцем отношений. В вашем примере обе стороны отношений думают, что они им владеют!

Вам необходимо добавить атрибут к вашему элементу set с помощью inverse="true". Эта директива говорит NHibernate не обновлять коллекцию с этого конца отношений.

0 голосов
/ 23 февраля 2010

Вы восстанавливаете временную коллекцию, потому что Master.Slaves все еще является исходной коллекцией.

Этого не произойдет в новом сеансе.

Если вы хотите обновить сущность в том же сеансе после сохранения, вам нужно session.Refresh () для этой сущности. Ваш метод DBManager.SaveObject может выполнить обновление после сохранения.

DbManager.SaveObject<T>( T entity )
{
    session.Save( entity );
    session.Refresh( entity );
}
0 голосов
/ 22 февраля 2010

Попробуйте использовать access = "backfield" вместо access = "property".

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