2012-01-03 31 views
2

我使用Nhibernate 3.2和流暢的nhibernate,我有兩個表客戶組和客戶,並且我使用TimeStamp列進行鎖管理版本控制。 我有以下類和映射這些類:批量更新,刪除,插入與版本控制無法正常工作

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個I創造客戶名單更新屬於特定的客戶羣是這樣的:

 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> 

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

謝謝您的回答,我想你的代碼,仍然無法正常工作。 – 2012-01-03 08:56:12

+0

但我在我的項目中使用.Net 3.5 – 2012-01-03 09:19:28

+1

我不認爲ADO.Net版本與您編譯的.Net版本相同。谷歌似乎說ADO.Net 3.5主要是關於EF,我懷疑NH可以掛鉤。 – Origin 2012-01-03 09:25:08