Пакетное обновление, удаление, вставка не работают правильно с контролем версий - PullRequest
2 голосов
/ 03 января 2012

Я использую Nhibernate 3.2 и свободно владею nhibernate, у меня есть две таблицы Customer Group и Customer, и я использую для управления версиями управления блокировками с помощью TimeStamp Column.У меня есть следующие классы и карты для этих классов:

public class Customer
{
    public Customer()
    {
    }
    public virtual int CustomerID { get; set; }
    public virtual CustomerGroup customerGroup { get; set; }
    public virtual int CustomerGroupID { get; set; }
    public virtual string CustomerRef { get; set; }
    public virtual string NameE { get; set; }
    public virtual string NameA { get; set; }
    public virtual byte[] TimeStamp { get; set; }
}

и его карта

 public class CustomerMap : ClassMap<Customer> {

    public CustomerMap() {
        Table("Customer");
        Id(x => x.CustomerID).GeneratedBy.Identity().Column("CustomerID");
        Version(x =>x.TimeStamp).CustomType("BinaryBlob").Generated.Always().Column("TimeStamp");
        DynamicUpdate();
        OptimisticLock.Version();
        References(x =>x.customerGroup).Column("CustomerGroupID").ForeignKey("CustomerGroupID");
        Map(x => x.CustomerRef).Column("CustomerRef").Length(30).Unique();
        Map(x => x.NameE).Column("NameE").Not.Nullable().Length(100).Unique();
        Map(x => x.NameA).Column("NameA").Length(100);

и для группы клиентов:

 public class CustomerGroup {
    public CustomerGroup() {
       Customers = new List<Customer>(3);
     }
    public virtual int CustomerGroupID { get; set; }
    public virtual IList<Customer> Customers { get; set; }
    public virtual byte[] TimeStamp { get; set; }
   }

и его карта:

 public CustomerGroupMap() {
        Table("CustomerGroup");
        Version(x => x.TimeStamp).CustomType("BinaryBlob").Generated.Always().Column("TimeStamp");
        DynamicUpdate();
        OptimisticLock.Version();
        Id(x => x.CustomerGroupID).GeneratedBy.Identity().Column("CustomerGroupID");
        HasMany(x => x.Customers).KeyColumn("CustomerGroupID");
  }

Когда я создаю обновление в списке клиентов, принадлежащих к определенной группе клиентов следующим образом:

        ISession Session = OpenSession();
        Session.BeginTransaction();
        var customerGroupInfo = Session.Query<CustomerGroup>().Fetch(x => x.Customers).Single<CustomerGroup>(x => x.CustomerGroupID == 98);
        foreach (var item in customerGroupInfo.Customers)
        {
            item.NameE = "abc";
            Session.Update(item);
        }
        Session.Transaction.Commit();

применяет эти операторы sql:

UPDATE Customer SET    NameE = 'abc' 
WHERE  CustomerID = 200 AND TimeStamp = 0x00000000000092EF  

SELECT customer_.TimeStamp as TimeStamp1_ FROM   Customer customer_
WHERE  customer_.CustomerID = 200 

UPDATE Customer SET    NameE = 'abc'
WHERE  CustomerID = 201 AND TimeStamp = 0x00000000000092F0 

SELECT customer_.TimeStamp as TimeStamp1_ FROM   Customer customer_
WHERE  customer_.CustomerID = 201

.,.

и каждое обновление и каждый выбор работают в одном цикле.Я устанавливаю свойство adonet.batch_size в конфигурации следующим образом:

<property name="adonet.batch_size">20</property>

Я прочитал в этот пост это поведение, основанное по умолчанию в Nhibernate 3.2.Какие-либо советы, чтобы заставить пакет работать правильно?

1 Ответ

2 голосов
/ 03 января 2012

Вы могли бы взглянуть на изменение Session.FlushMode на что-то, кроме Автоматического. Таким образом, вы можете сделать что-то вроде этого:

Session.FlushMode = NHibernate.FlushMode.Never
foreach (var item in customerGroupInfo.Customers)
{
    item.NameE = "abc";
    Session.Update(item);
}
Session.Flush();
Session.Transaction.Commit();
// Perhaps changing the flushmode after commit?
Session.FlushMode = NHibernate.FlushMode.Auto;

Редактировать:

Неважно, посмотрите этот отрывок из документов: http://nhibernate.info/doc/nh/en/index.html#batch

Похоже, что пакетирование не сочетается с оптимистической блокировкой.

NHibernate поддерживает пакетные команды обновления SQL (INSERT, UPDATE, DELETE) со следующими ограничениями:

.NET Framework 2.0 or above is required,

**the Nhibernate's drive used for your RDBMS may not supports batching,**

since the implementation uses reflection to access members and types in System.Data assembly which are not normally visible, it may not function in environments where necessary permissions are not granted

**optimistic concurrency checking may be impaired since ADO.NET 2.0 does not return the number of rows affected by each statement in the batch, only the total number of rows affected by the batch.**
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...