【问题标题】:How can I prevent logical duplicates with EF Code first?如何首先使用 EF 代码防止逻辑重复?
【发布时间】:2011-11-12 01:57:27
【问题描述】:

给定一个像 Person 这样的简单类,具有 FirstName、LastName 和 DOB 属性以及 Id 属性(这是主键)。

当我调用我的创建操作时,我想执行验证以确定我传入的具有 FirstName、LastName 和 DOB 属性的模型是否恰好匹配任何已经存在的记录。在这种情况下,我想排除 Id 属性,因为进入应用程序的模型还没有,并且会产生误报。

目前我只是像这样使用 Any 扩展方法...

if (!context.People.Any(x => x.FirstName == model.FirstName && x.LastName == 
model.LastName && x.DOB == model.DOB))

这当然有效,但完全不优雅。

肯定有更好的方法吗?

【问题讨论】:

  • 您可以通过对数据库的独特约束来避免此类事情,然后在代码中进行适当的错误处理。如果您想在保留值之前检查重复项,那么我认为 Any() 虽然不是很优雅,但完全可以。
  • 这不是重复的,你提到的问题的答案是我说我明确想要避免的

标签: c# asp.net-mvc ef-code-first


【解决方案1】:

如果唯一性是业务需求,那么您应该在具有唯一约束的数据库中处理它。然后,您无需检查,数据库将抛出异常并告诉您何时违反。您处理异常并告诉用户他们已经在系统中。

【讨论】:

  • 我不同意这种做法。我认为最好使用验证器。除了验证之外,您还可以有一个唯一的约束,但您不应该期望会发生这样的异常。不过,这只是我的看法。
  • 我也不同意,这是一个非常不稳定的解决方案 - 通过异常控制应用程序的流程在我的不良代码属性列表中非常重要。
  • @keithwarren7 - 这不是控制流。您没有使用异常来决定更新记录或插入记录。那会很糟糕。这是用户插入重复记录的情况。您唯一的其他选择是先查询数据库,但您说您不想这样做。
【解决方案2】:

问题是您不想直接在控制器中看到 Any 调用还是您根本不喜欢该调用?

如果是前者,则使用验证框架向控制器隐藏细节。如果是后者,那么您可以在数据库中创建某种存储过程/函数并调用它。

不过,我并不认为这段代码不好。我只是认为这需要一个验证。 FluentValidation 对此非常有用,但 DataAnnotations 也可以。

【讨论】:

  • 我想真正的问题是,对 Any 的调用取决于在每个实体的情况下写出每个非键属性,而不是进行一个通用调用。我现在在想我可能会编写一个扩展方法来接受模型并匹配非键属性的值。所以归根结底,我可以问这个问题 - “我怎么能比这更懒惰......”
  • 编写该扩展方法正是我正在努力回答您的问题。这似乎是最好的解决方案。你怎么能更懒惰?在 SO 上询问它,看看是否有人会为你写它;)
  • @keithwarren7 - 扩展方法不是一个好主意,因为扩展方法是静态的。您不想在扩展方法中查询数据库,因为它会在程序的整个生命周期内保持打开的连接。
猜你喜欢
  • 1970-01-01
  • 2020-04-07
  • 1970-01-01
  • 2011-08-11
  • 2016-06-06
  • 2013-10-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多