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);
}
}
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
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();
}
}
}
}
}
精彩评论