2012-01-03 10 views
2

私はNhibernate 3.2を使用しており、流暢なnhibernateを使用しています。顧客グループと顧客テーブルが2つあり、タイムスタンプ列によるロック管理バージョン管理に使用します。 私は、これらのクラスのための次のクラスとマップを持っている:バージョン管理でバッチ更新、削除、挿入が正しく動作しない

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"); 
    } 

Whe nは私はこのような特定の顧客グループに属している顧客のリストに更新を作成します。

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 

 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文を適用します。 。 。

すべてのアップデートとすべての選択は、1回の往復で動作します。 は、私はこのような構成のプロパティadonet.batch_sizeプロパティを設定します。

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

私はthis postにNHibernateは3.2でデフォルトによって設立され、この動作をお読みください。 バッチを正しく作成するためのヒント

答えて

2

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.** 
+0

は、私はあなたのコードを試しても正常に動作しない、あなたの答えをいただき、ありがとうございます。 –

+0

私のプロジェクトでは.Net 3.5を使用しています。 –

+1

ADO.Netのバージョンはコンパイルする.NETバージョンと同じではないと思います。 Googleは、ADO.Net 3.5は主にEFに関するものだと言いますが、これはNHがフックできるとは思っていません。 – Origin

関連する問題