2011-02-01 36 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

相关问题