NHibernate: Как идентификатор удостоверения личности обновляется при сохранении временного экземпляра? - PullRequest
3 голосов
/ 04 февраля 2011

Если я использую сеанс для каждой транзакции и вызову:

session.SaveOrUpdate (entity) исправлено:
session.SaveOrUpdateCopy (entity)

.. и entity - это временный экземпляр с identity-Id = 0.Должна ли вышеуказанная строка автоматически обновить Id объекта и сделать экземпляр постоянным?Или это должно быть сделано на транзакции.Или я должен каким-то образом кодировать это явно?

Очевидно, что идентификатор строки базы данных (новый, так как временный) генерируется автоматически и сохраняется как некоторое число, но я говорю о фактическом экземпляре параметра здесь.Который является экземпляром бизнес-логики.


РЕДАКТИРОВАТЬ - Последующие действия, связанные с проблемой.

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

public class StoreMap : ClassMap<Store>
{
    public StoreMap()
    {
        Id(x => x.Id).GeneratedBy.Identity();
        Map(x =>  x.Name);
        HasMany(x => x.Staff)    // 1:m
            .Cascade.All();       
        HasManyToMany(x => x.Products)  // m:m
            .Cascade.All()
            .Table("StoreProduct");    
    }
}

public class EmployeeMap : ClassMap<Employee> 
{
    public EmployeeMap()
    {
        Id(x => x.Id).GeneratedBy.Identity();   
        Map(x => x.FirstName);
        Map(x => x.LastName);
        References(x => x.Store);    // m:1
    }
}

public class ProductMap : ClassMap<Product>
{
    public ProductMap() 
    {
        Id(x => x.Id).GeneratedBy.Identity();
        Map(x => x.Name).Length(20);
        Map(x => x.Price).CustomSqlType("decimal").Precision(9).Scale(2);
        HasManyToMany(x => x.StoresStockedIn)
        .Cascade.All()
        .Inverse()
        .Table("StoreProduct");
     } 
}

EDIT2

Определения классов:

   public class Store
{
    public int Id { get; private set; }
    public string Name { get; set; }
    public IList<Product> Products { get; set; }
    public IList<Employee> Staff { get; set; }

    public Store()
    {
        Products = new List<Product>();
        Staff = new List<Employee>();
    }


    // AddProduct & AddEmployee is required. "NH needs you to set both sides before
    // it will save correctly" 

    public void AddProduct(Product product)
    {
        product.StoresStockedIn.Add(this);
        Products.Add(product);
    }

    public void AddEmployee(Employee employee)
    {
        employee.Store = this;
        Staff.Add(employee);
    }
}

public class Employee
{
    public int Id { get;  private set; }
    public string FirstName { get;  set; }
    public string LastName { get;  set; }
    public Store Store { get; set; }
}

public class Product
{
    public int Id { get; private set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
    public IList<Store> StoresStockedIn { get; private set; }
}

Ответы [ 4 ]

3 голосов
/ 05 февраля 2011

Что касается вашего вопроса, то всякий раз, когда вы сбрасываете сеанс, это когда ваша сущность сохраняется в базе данных. При сохранении вашей (новой) сущности NHibernate генерирует для вас идентификатор, используя предоставленный вами генератор.

Имейте в виду, что генератор идентичности не рекомендуется (см. этот пост Ayende ). Когда вы используете генератор идентификаторов, ваша новая сущность сохраняется в базе данных при сохранении, даже если вы не выполняете сброс в базу данных. Причина этого заключается в том, что NHibernate должен предоставить вам идентификатор для сущности, чего он не может сделать без обращения к базе данных.

Лучшим решением было бы использовать что-то вроде генератора Guid или HiLo, если вам нужны «нормальные» значения. Таким образом, вы можете сохранить свою сущность, не прибегая к обходу базы данных, что позволяет значительно повысить производительность (пакетная обработка приходит на ум).

2 голосов
/ 04 февраля 2011

Я не уверен, что понимаю ваш вопрос.Фактическое сохранение в базе данных происходит, когда сеанс сбрасывается (например, путем фиксации транзакции).Вызов SaveOrUpdate () сам не сохраняет объект, он просто сообщает сеансу, что объект должен быть сохранен при сбросе сеанса.

Предполагая, что идентификатор объекта отображается в поле идентификаторабаза данных и что ваше сопоставление сообщает NHibernate, что идентификатор устанавливается базой данных, тогда идентификатор, установленный базой данных, будет установлен в качестве идентификатора объекта при его сохранении.

1 голос
/ 04 февраля 2011

Nhibernate установит свойство ID вашей сущности сразу после вызова SaveOrUpdate.

0 голосов
/ 05 февраля 2011

Я заметил, что сохранил, позвонив по телефону:

session.SaveOrUpdateCopy(entity); 

.., который НЕ обновляет идентификатор.Но при изменении на:

session.SaveOrUpdate(entity);

.. Идентификаторы переходной сущности будут обновлены.

Возможно, я неправильно понял документацию (?). В разделе 9.4.2 говорится:

SaveOrUpdateCopy (Object o) ... Еслиданный экземпляр является несохраненным или не существует в базе данных, NHibernate сохранит его и вернет как новый постоянный экземпляр.

Это только я, или это не похоже на переходный процессобъект ( несохраненный ), будет " возвращен как постоянный "?Разве это не значит с обновленным идентификатором?Буду признателен за разъяснение, как правильно интерпретировать это предложение (?)

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