删除子对象时发生 NHibernate StaleStateException

发布于 2024-10-15 02:48:58 字数 1755 浏览 0 评论 0原文

是否可以从 StackTrace 中说出这个异常的起源?

StaleStateException:  Unexpected row count: 0; expected: 1

我在多个 DataGridView 中显示父/子对象集合,并执行各种添加/删除/保存命令。尝试删除子行/实体时会发生此异常。我使用DefaultCascadeAll 约定

发生此异常后,相应的父实体已从数据库中删除,即使没有要求这样做。因此,如图所示,下次我启动程序时;商店 Id=55 不存在。

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

StackTrace: 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);    
    }
}

编辑1:

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

Is it possible to say something of the origin of this exception from the StackTrace?

StaleStateException:  Unexpected row count: 0; expected: 1

I'm displaying parent/child object collections in multiple DataGridViews, and perform varioius add/delete/save commands. This exception occur when attempting to delete a child row/entity. I use DefaultCascadeAll convention.

After this exception, the respective parent entity has been deleted from the database, even though that was not called for. So in the image shown, next time I start the program; Store Id=55 is non existing.

Program window: http://img822.imageshack.us/img822/4686/ss20110201212511.png

StackTrace: http://img145.imageshack.us/img145/408/ss20110201211702.png

Mappings:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我只土不豪 2024-10-22 02:48:58

要修复您似乎不想要的级联,请将映射更改为 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,
贝里尔

To fix the cascades that you don't seem to want, change the mapping to Cascade.None

For a quick fix to the stale state do something like:

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

It's a horrible design but maybe enough to get you to a better one after you get past the error.

HTH,
Berrryl

一个人的夜不怕黑 2024-10-22 02:48:58

此异常的可能原因是存储库方法无法处理(拒绝)瞬态实体,并且可能还因为分离的实体未附加到会话。因此下面的代码修复了这个问题,并避免了 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();
                  }
                }
            }
        }
    } 

The likely cause of this exception was that the repository method was not able to handle (reject) transient entities, and perhaps also that detached entities were not attached to the session. So the code below fixed that, and avoided the StaleStateExceptions.

Still, as pointed out, this short session scope is for most cases not a good solution.

    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();
                  }
                }
            }
        }
    } 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文