【发布时间】:2021-05-08 05:23:14
【问题描述】:
我有一项服务,它每秒将数据发布到网络服务器 (asp.net core 3.1),然后我使用 EF Core 3.1 将这些数据存储到 sql 服务器。 到目前为止,我在尝试存储新数据时,分别为每个新数据行:
- 检查数据库中是否存在数据实体(实体类型在
OnModelCreating()方法中配置了.IsUnique()索引) - 如果不存在 - 添加单个实体
- DBContext.SaveChanges()
但是,这在 sql server 上似乎有点“繁重”,有很多调用。它在 Azure 上运行,有时似乎数据库出现了一些问题,并且 Web 服务器开始返回 500(据我所知,内部服务器错误)。当有人调用 web 服务器上的另一个控制器并尝试从 sql 服务器检索一些数据(更大的块)时,有时会发生这种情况。 (这可能是另一个问题 - 关于 Azure SQL 服务器的可靠性)
最好在网络服务器上保留一个缓冲区并一次性保存所有内容,例如:DBContext.AddRange(entities),时间分辨率稍粗一些(即每分钟)?我不知道如果一个或多个数据重复会发生什么?那些不是重复存储的还是所有插入都被拒绝? (我似乎找不到对此的解释)。
非常感谢您对此事的任何帮助。
编辑 2021-02-08: 我尝试扩展一下情况:
我无法控制:MQTT 代理(发布消息)
在我的控制之下:
- MQTT 客户端(目前为 azure webjob),订阅 MQTT Broker
- ASP.NET 服务器
- SQL 数据库
MQTT 客户端正在从 mqtt 代理收集来自不同传感器的消息并将其分组为一种(或多或少)可以直接存储在数据库中的格式。
asp.net 服务器充当 mqtt 客户端和 sql 数据库之间的中间人。 BUT 还向访问该网站的任何人持续发送“实时”更新。所以目前网络服务器有很多工作(也许问题出现在这里??)
- 从 MQTT 服务接收数据
- 在数据库中存储/检索数据
- 为访问者提供来自 MQTT 客户端的“实时”数据以及来自数据库的历史数据
希望这有助于理解。
【问题讨论】:
-
请分享实体配置代码。而且,您无法在本地使用
AddRange()测试行为的任何具体原因? -
仔细阅读这篇文章,我觉得应该对你有用,使用
Transactions可以解决你的问题。 -
我认为您可能需要找出问题的根本原因,而不是尝试在此保存操作中修复它。也许您在 azure 中的 sql server 层对于负载来说太有限了..或者可能还有其他事情发生。此外,既然有一个索引,为什么不总是添加而不检查?如果它已经存在,你只会收到一个错误,就是这样。此外,EF 始终在事务下执行您的保存,因此您无需手动执行此操作。
-
@jpgrassi,问题的根源在于您必须在事务中执行此操作或离开 EF。首先,您必须选择数据库中存在的 ID - 创建大的
IN查询,将该列表返回给客户端,过滤掉已经存在的记录,然后context.AddRange()和context.SaveChanges().一切都需要时间并且事务会阻止其他人。
标签: sql-server entity-framework-core azure-sql-database asp.net-core-3.1 mqttnet