2011-02-01 68 views
0

是否有可能從StackTrace中說出這個異常的來源?關於刪除子對象的NHibernate StaleStateException

StaleStateException: Unexpected row count: 0; expected: 1 

我在多個DataGridViews中顯示父/子對象集合,並執行varioius添加/刪除/保存命令。嘗試刪除子行/實體時會發生此異常。我使用DefaultCascadeAll約定

發生此異常之後,即使未調用相應的父實體,也會從數據庫中刪除相應的父實體。所以在下面的圖片中,我開始了這個程序。商店Id = 55不存在。

程序窗口:http://img822.imageshack.us/img822/4686/ss20110201212511.png

堆棧跟蹤:http://img145.imageshack.us/img145/408/ss20110201211702.png

映射:

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

} 

public class EmployeeMap : ClassMap<Employee> 
{ 

    public EmployeeMap() 
    { 
     Id(x => x.Id);     
     Map(x => x.FirstName); 
     Map(x => x.LastName); 
     References(x => x.Store);  
    } 
} 

EDIT1:

private void btnDeleteEmployee_MouseDown(object sender, MouseEventArgs e) 
    { 
     var item = bsEmployees.Current; // BindingSource 
     Employee emp = new Employee(); 

     if (item.GetType() == emp.GetType()) 
     { 
      emp = (Employee)bsEmployees.Current; 
      EmployeeRepository.Delete(emp); 
     }    
    } 
+0

您在不同的會話和事務中讀取員工。問題在於調用Delete之前的代碼部分。 – Paco 2011-02-01 20:15:05

回答

0

此異常的可能原因是,庫法是無法處理(拒絕)短暫的實體,或許也是分離的實體並沒有連接到會議。所以下面的代碼解決了這個問題,並避免了StaleStateExceptions。

不過,正如指出的那樣,這個短期會議的範圍對大多數情況來說並不是一個好的解決方案。

public static void Delete(Employee employee) 
    { 
     using (ISession session = FNH_Manager.OpenSession()) 
     { 
      using (ITransaction transaction = session.BeginTransaction()) 
      { 
       if (Employee.Id != 0) 
       { 
        var emp = session.Get(typeof(Employee), employee.Id); 

        if (emp != null) 
        { 
        session.Delete(emp); 
        transaction.Commit(); 
        } 
       } 
      } 
     } 
    } 
0

爲了解決這個問題,你似乎並不想級聯,改變映射到Cascade.None

對於一個快速修復失效狀態做這樣的事情:

private void btnDeleteEmployee_MouseDown(object sender, MouseEventArgs e) 
{ 
    if (item.GetType() == emp.GetType()) 
    { 
     emp = EmployeeRepository.GetById(((Employee)beEmployees.Current).Id); 
     EmployeeRepository.Delete(emp); 
    }    
} 

這是一個可怕的設計,但也許足以讓你在遇到錯誤後找到更好的設計。

HTH,
Berrryl

相關問題