是否有一种方法可以清除EF缓存/本地项目,而不会对数据库造成任何改变
本文关键字:项目 任何 改变 数据库 一种 方法 EF 缓存 清除 是否 | 更新日期: 2023-09-27 18:07:13
基本上,我将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!
}
}
当然,客户-订单是one-to-many
(1:m)关系。
我想避免在上面的场景中,当有一些属于被删除的客户的上下文加载的订单时抛出的异常。例外是:
"无法更改关系,因为一个或多个外键属性不可为空。进行更改时关系时,相关的外键属性设置为空值。如果外键不支持空值,则建立新的关系必须定义,外键属性必须分配另一个非空值,否则必须删除不相关的对象。"
所以,我想知道是否有可能在调用存储过程之后和删除用户之前清除<DbSet>.Local
中的一些/所有订单,而不引起对数据库的任何更改。
我想可以使用Detach,但这意味着我应该循环。
你有什么建议吗?
编辑:我是EF的新手,我现在正在使用ADO完成存储库后集成EF。NET,是的,提单一直保持不变…因此,我在这一点上尝试以最小的努力进行集成。
注意:我不能修改数据库结构
此功能从实体框架核心5开始可用!
让DbContext停止跟踪所有当前跟踪的实体:
myDbContext.ChangeTracker.Clear();
我个人会让每个存储库方法使用自己的上下文,在方法结束时保存自己的更改等,然后使用TransactionScope
来确保操作是原子的。
void DeleteAllOrdersOfCustomer(Guid customerUID)
{
using (var context = new Context())
{
...
context.SaveChanges();
}
}
…
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();
}
可以刷新
它可能有点棘手,我不知道使用它有多贵。您将需要使用RefreshMode
Enum,我假设您需要StoreWins
。
顺便说一句,你可能能够加速你的EF删除,而不是批处理,但这是一个不同的问题。
我一直在使用dbset
的SqlQuery
来达到这个目的,这样:
context.xdbset.SqlQuery("storedprocedure; select * from xdbset");
查询调用存储过程,然后调用select *...
,这在这里是必要的,因为查询结果必须包含上下文构建"xdbset"对象所需的数据格式。