【问题标题】:Entity Framework Core: Transaction between reading and deleting dataEntity Framework Core:读取和删除数据之间的事务
【发布时间】:2018-09-12 20:56:38
【问题描述】:

我在 .NET Core REST API 中遇到了 Entity Framework Core 的问题。

示例数据模型:

桌屋(id,名称) 桌房(id、houseId、名称)

一个房子可以有多个房间,一个房间只能在一个房子里。

我在删除房间时出现问题。每次用户请求删除房间时,我都会检查房间是否是房子里的最后一个房间,如果它是最后一个房间,我也会删除(空的)房子。

  Room room = dbContext.Room
    .Include(r => r.House).ThenInclude(h => h.Rooms)
    .Where(r => r.id == id)
    .SingleOrDefaultAsync();

  if (room.House.Rooms.Count > 1) {
    // other rooms are present
    dbContext.Room.Remove(room);
  } else {
    // delete house if it is the last room
    dbContext.House.Remove(room.House);
  }

  dbContext.SaveChanges();

问题是我们的 UI 不会在一次调用中删除房屋,它会为房屋中的每个房间调用删除房间(并期望房屋与最后一个房间一起自动删除)。这会导致问题。每个房间都加载房子实体,检查它是否是最后一个房间,识别其他房间,房间被删除,空房子仍然存在。

这无论如何都可以解决(所以空房子不会留下)例如有交易吗?

【问题讨论】:

  • 这听起来更像DbContext 终身问题。

标签: c# .net-core entity-framework-core


【解决方案1】:

是和不是。您可以将其包装到事务中 - 这很简单。

https://docs.microsoft.com/en-us/ef/core/saving/transactions

展示方法。

你基本上只是创建一个事务:

使用 (var transaction = context.Database.BeginTransaction())

或者,您可以在 DbConnection 上使用 DbTransaction。相同的链接。

但是你的代码组织得很糟糕。

每个房间都加载房屋实体,检查它是否是最后一个房间,识别其他房间 房间,房间被删除,空房子仍然存在。

听起来有人将数据库完全抽象到了一些不错的存储库反模式后面——而那(不是事务)现在又回来咬你了。很可能每个被删除的房间都使用一个单独的存储库 - 并且繁荣,交易没有帮助。

重构时间。

【讨论】:

  • 您介意详细说明“您的代码组织得很糟糕”吗?
【解决方案2】:

最好的解决方案可能是创建一种新的单独方法来删除房屋,以便在一次调用中处理整个事情。

如果确实有一些问题阻止您完成 DeleteHouse 方法,您可以通过锁定来解决您的问题。我认为您的基本问题是线程竞争条件。为您的删除房间代码添加锁以解决该问题。

lock(_deleteRoomLock) 
{ \\Your delete room code }

这种模式的缺点是,您最终会在服务器端代码中围绕删除房间创建相当大的瓶颈。

链接到关于锁定https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/lock-statement的文档

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-03
    • 2018-05-24
    • 2016-12-05
    • 1970-01-01
    • 1970-01-01
    • 2011-05-07
    • 2021-02-11
    相关资源
    最近更新 更多