0

我想在一个事务中使用 Telerik 开放访问从多个表中删除 - 因此,如果任何删除出现问题,它们都会回滚。

这是我在阅读文档后提出的代码,但是我怀疑每个“DeleteAll”都在运行一个单独的事务,而不是在最后等待“SaveChanges()”。真的吗?如果是这样,我还能如何完成我想做的事情(即在一个事务中删除所有内容)?

int deleted = 0;
using (PortalContext dbContext = new PortalContext())
{
    var bars = dbContext.GetAll<xxx>().Where(x => x.a == user.a && x.b == b && x.c >= sessionStart);
    deleted += bars.DeleteAll();
    var badss = dbContext.GetAll<yyy>().Where(x => x.a == user.a && x.b == b && x.c >= sessionStart);
    deleted += badss.DeleteAll();
    var bads = dbContext.GetAll<zzz>().Where(x => x.a == user.a && x.b == b && x.c >= sessionStart);
    deleted += bads.DeleteAll();
    var trades = dbContext.GetAll<aaa>().Where(x => x.a == user.a && x.b == b && x.c >= fromTime);
    deleted += trades.DeleteAll();
    var balances = dbContext.GetAll<bbb>().Where(x => x.a == user.a && x.b == b && x.c >= fromTime);
    deleted += balances.DeleteAll();

    dbContext.SaveChanges();
}
4

1 回答 1

3

你的怀疑是正确的。DeleteAll 在单独的事务中立即执行,并且不等待 SaveChanges。因此,您将不得不使用正常的 Delete 方法。您将必须获取要删除的对象,然后遍历它们,为每个对象调用 Delete,然后在最后调用 SaveChanges:

using (EntitiesModel context = new EntitiesModel())
{
    var rentalOrdersToDelete = context.RentalOrders.Where(order => order.RentalOrderID < 10);
    var carsToDelete = context.Cars.Where(car => car.CarID < 5);
    foreach (RentalOrder order in rentalOrdersToDelete)
    {
        context.Delete(order);
    }
    foreach (Car car in carsToDelete)
    {
        context.Delete(car);
    }
    context.SaveChanges();
}

请注意,将生成的类似 SQL 语句也将一起批处理,因此性能应该很好。

此外,如果您将长期存在的上下文对象用于除此多次删除之外的各种其他操作,我建议确保上下文中没有其他挂起的更改(没有打开的事务),这样您就不会秘密推送除了调用 SaveChanges 时的删除之外,数据库中的任何其他内容。您可以使用 context.HasChanges 属性进行检查。

于 2014-08-25T14:53:10.633 回答