EF6 - 有没有办法清除EF缓存/本地项目而不会对数据库进行任何更改?

Lea*_*ner 8 .net c# entity-framework

基本上我将EF与一次调用混合存储过程进行一些批量删除,否则EF太慢.

以下是此场景的一些伪代码(实际上我有更复杂的代码):

public void RemoveCustomer(int customerUID)
{
   // this code is running in one db transaction
   {
      // retrieve certain orders of particular customer using EF
      var orders = repoOrders.GetOrdersOfCustomer(filter, customerUID);

      // do something with above orders before deletion using EF
      repoX.DoSomethingWithOrders(orders);

      // call SP to delete all orders of customer 
      repoOrders.DeleteAllOrdersOfCustomer(customerUID);  // this calls a stored procedure

      // delete customer using EF 
      repoCustomers.DeleteCustomer(customerUID);  // throws exception due to relationship!
   }
}
Run Code Online (Sandbox Code Playgroud)

客户订单当然是one-to-many(1:m)关系.

我想在上面的场景中避免在属于被删除的客户的上下文加载某些订单时抛出的异常.例外情况是:

"由于一个或多个外键属性不可为空,因此无法更改关系.当对关系进行更改时,相关的外键属性将设置为空值.如果外键是如果不支持空值,则必须定义新关系,必须为foreign-key属性分配另一个非空值,或者必须删除不相关的对象."

因此,我想知道是否可以<DbSet>.Local在调用存储过程之后和用户被删除之前清除部分/全部订单而不会对数据库造成任何更改.

我猜Detach可以用,但这意味着我应该循环使用.

你会推荐什么?

编辑:我是EF新手,我现在正在使用ADO.NET完成存储库之后集成EF,是的,BL保持不变......所以我尝试这种集成,此时只需要很少的努力.

注意:我无法对数据库结构进行更改.

Jos*_*hee 17

此功能从 Entity Framework Core 5 开始可用!

要使 DbContext 停止跟踪所有当前跟踪的实体:

myDbContext.ChangeTracker.Clear();
Run Code Online (Sandbox Code Playgroud)


Str*_*ior 6

我个人使每个存储库方法使用自己的上下文,在方法结束时保存自己的更改等,然后使用a TransactionScope来确保操作是原子的.

void DeleteAllOrdersOfCustomer(Guid customerUID)
{
    using (var context = new Context())
    {
       ...
       context.SaveChanges();
    }
}
Run Code Online (Sandbox Code Playgroud)

...

using (var ts = new TransactionScope())
{
   // call SP to delete all orders of customer 
   repoOrders.DeleteAllOrdersOfCustomer(customerUID);  // this calls a stored procedure

   // delete customer using EF 
   repoCustomers.DeleteCustomer(customerUID);  // throws exception due to relationship!
   ts.Complete();
}
Run Code Online (Sandbox Code Playgroud)


The*_*Wes 2

刷新应该可以解决问题

它可能有点棘手,我不知道使用起来有多贵。您将需要使用RefreshMode枚举,我假设您想要StoreWins

顺便说一句,您也许可以加快 EF 删除速度,而不是批量删除,但这是另一个问题。