【问题标题】:Entity Framework - Checking for duplicate values prior to updating the record实体框架 - 在更新记录之前检查重复值
【发布时间】:2022-01-13 18:10:50
【问题描述】:

您能帮帮我吗?我正在尝试使用实体框架更新我的数据库中的客户表(前端调用我在 API 中的端点来更新记录)。在更新记录之前,我需要做一些验证(例如确保没有在数据库中为客户创建重复的电子邮件地址)。

以下是我当前的代码:

if (await DuplicateEmailAddress(learnerEdit.EmailAddress)) 返回 BadRequest("该邮箱地址已被其他学员使用。");

我检查重复的方法:

私有异步任务 DuplicateEmailAddress(string emailAddress) { 返回等待 _context.Learners.AnyAsync(x => x.EmailAddress == emailAddress); }

当我使用 Postman 测试我的 API 调用时,我收到错误消息,因为查询正在测试我正在更新的记录。有没有办法在验证时排除我正在更新的记录?

谢谢

【问题讨论】:

  • 根据您的需要,在电子邮件列(全局唯一邮件)或复合(customerId、emailAddress)上使用某种形式的唯一约束来强制数据库上的唯一性可能是一个更好的主意,如果电子邮件应该只在客户帐户中是唯一的。在没有数据库支持的情况下尝试在 EF 中强制执行唯一性是等待竞争条件出现的解决方案
  • 你可以试试:_context.Learners.AsNoTracking().AnyAsync(x => x.EmailAddress == emailAddress);
  • 我的建议是阅读这方面的设计模式。责任链或规范模式的示例。这也可以提高代码的质量
  • @grek40 感谢您提供有用的见解。我绝对希望电子邮件地址在数据库中是唯一的。但是,我需要多考虑一下,因为我有客户也可以是供应商的场景,所以我需要能够同时保存他。需要考虑一些数据库设计。谢谢
  • @klekmek 您的推荐非常有效。谢谢!

标签: c# asp.net entity-framework


【解决方案1】:

对于 EF 端检查,您应该修改您的条件以排除您要编辑的条目。类似的东西

_context.Learners.AnyAsync(x => x.EmailAddress == emailAddress && x.Id != learnerEdit.Id);

正如推荐的那样,您应该另外向数据库添加一个唯一约束。否则你的代码对竞争条件是开放的,当你检查时你的数据库是好的,但当你 SaveChanges 时已经包含重复项

【讨论】:

  • 谢谢@Grek40。我发现 AsNoTracking 选项到目前为止一直有效。我尝试了您的方法,但是作为开发新手,我不太确定您从哪里获得 learnerEdit 的价值。
  • @Jeremiah 您必须将 learnerEdit 而不仅仅是 learnerEdit.EmailAddress 作为参数传递给您的重复检查函数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-11-16
  • 2014-07-02
  • 2021-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-23
相关资源
最近更新 更多