C# 如何首先使用EF代码防止逻辑重复?

C# 如何首先使用EF代码防止逻辑重复?,c#,asp.net-mvc,ef-code-first,C#,Asp.net Mvc,Ef Code First,给定一个简单的类,如Person,具有FirstName、LastName和DOB属性以及Id属性(主键) 当我调用我的create操作时,我想执行一次验证,以确定我传入的具有FirstName、LastName和DOB属性的模型是否与任何已经存在的记录匹配。在这种情况下,我想排除Id属性,因为进入应用程序的模型还没有Id属性,并且会产生误报 目前我只是在使用任何扩展方法,就像这样 if (!context.People.Any(x => x.FirstName == model.Firs

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

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

目前我只是在使用任何扩展方法,就像这样

if (!context.People.Any(x => x.FirstName == model.FirstName && x.LastName == 
model.LastName && x.DOB == model.DOB))
这当然有效,但完全不优雅


当然有更好的方法吗?

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

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


不过,我并不认为这段代码很糟糕。我只是觉得这需要一个验证。FluentValidation在这方面非常好,但是DataAnnotation也可以工作。

如果唯一性是一项业务需求,那么您应该在数据库中使用唯一性约束来处理它。然后,您不需要进行检查,数据库将抛出一个异常,并在违反该异常时告诉您。您可以处理异常并告诉用户它们已经在系统中。

您可以通过数据库上的独特约束避免类似的情况,然后在代码中进行正确的错误处理。如果您想在值被持久化之前检查重复项,那么我认为
Any()
,虽然不太优雅,但完全可以。可能的重复项不是重复项,您提到的问题的答案是我说过的我明确希望避免的,我想真正的问题是,对Any的调用取决于在每个实体的情况下写出每个非键属性,而不是一个泛型调用。我现在在想,我可能会编写一个扩展方法来接受模型并匹配非键属性的值。所以底线是,我可以问这样一个问题-‘我怎么能比这更懒?’写扩展方法正是我用来回答你问题的。这似乎是最好的解决办法。你怎么能更懒呢?问一下,看看是否有人会为你写这封信(当然;)@keithwarren7-扩展方法是个坏主意,因为扩展方法是静态的。您不希望在扩展方法中查询数据库,因为它会在程序的生命周期内保持打开的连接。我不同意这种方法。我认为最好使用验证器。除了验证之外,您还可以有一个唯一的约束,但是您不应该期望出现这样的异常。不过,这只是我的观点。我也不同意,这是一个非常不稳定的解决方案-通过异常控制应用程序流在我的坏代码属性列表中非常重要。@keithwarren7-这不是控制流。您没有使用异常来决定更新记录或插入记录。那太糟糕了。这是用户插入重复记录的情况。你唯一的选择是先查询数据库,但你说你不想这样做。