实体框架核心存储库模式 - 重复检查

Posted

技术标签:

【中文标题】实体框架核心存储库模式 - 重复检查【英文标题】:Entity Framework Core Respository Pattern - Duplication Check 【发布时间】:2018-06-03 04:22:22 【问题描述】:

我正在尝试制定一个解决方案来检查是否有任何不应重复的字段添加了会违反此规则的行。我正在使用存储库模式,所以我想在存储库中创建一个方法来执行此操作。

在这个例子中,我试图添加一个公司,在控制器中添加它之前,它会在 CompanyRespository 中调用这个方法:

    public bool Exists(Company company, bool ignoreId)
    
        if (!ignoreId)
        
            if (context.Companies.Any(c => c.Id == company.Id)) return true;
        
        if (context.Companies.Any(c => c.TextId == company.TextId)) return true;
        if (context.Companies.Any(c => c.Email == company.Email)) return true;
        if (context.Companies.Any(c => c.PhoneNumber == company.PhoneNumber)) return true;
        return false;
    

我面临的问题是尝试返回错误,以便控制器可以将错误发送给客户端。显而易见的解决方案是只发送异常而不是返回 true。但是,如果我调用它只是为了说明是否有一家公司具有这些参数,那么我不希望发送异常,我只想在两种情况下都使用布尔值。

精简的问题:在这种情况下创建另一个返回异常而不是布尔值的方法 CheckDuplication() 是不好的做法吗?如果是,那么在 Entity Framework Core 中保存到数据库之前检查重复字段的正确方法是什么?

【问题讨论】:

使用更复杂的返回对象来保存所需的信息。类似于 ModelState 的使用方式。 我倾向于同意@Nkosi。为什么不只返回一个模型,其中有两个属性,一个是 IEnumerable 或 IList (对您来说有意义的),另一个是指示存在的布尔值? [为清楚起见进行了编辑。] PS 我不认为将存在检查和验证检查分开存在本质上的问题。拥有一个只返回布尔值的 Exists() 方法和某种抛出异常或返回某种可枚举异常的 Validate() 方法是很好的。如果将这两件事合并到一个模型中没有意义,那就不要这样做。坚持你原来的计划。它的缺点是每次向表中添加新字段时都需要维护两种方法。也有可能将这一切整合到一种方法中以返回一个对象实际上会使其变得更笨重。 mmm... 为什么不放 ON DB(如果您使用的是 SQL 数据库 ..不是如果您使用的是 MongDB ..)唯一索引或一些检查约束? ..所以当你尝试保存它时 ..EF 为你做检查? 认为这两种方法将是与 validate 方法一起使用的方式,该方法返回列表,异常被解析到控制器中的 ModelState。我已经在使用唯一约束,但我在互联网上找到的唯一方法是捕获异常,然后大量转换为不同的对象和笨重的代码,我想要一个更简洁的解决方案。 【参考方案1】:

有一个单独的验证检查会很好,并且允许您编写一个对用户更友好的应用程序。但是,不要错误地依赖此检查来确保数据完整性。多线程将是引起关注的主要原因。 Sql DB 可以更好地保护数据完整性,因此我建议在每个字段上定义唯一约束(例如查看Setting unique Constraint with fluent API?)。当然,这会引发 EF 异常,但可以捕获并检查这些异常以确定它们是否违反了约束。这样,如果需要,您仍然可以返回布尔值。

附带说明,可以通过使用 OR(||) 更有效地编写 Exits 方法,这样您就不必触发这么多 sql 查询。

【讨论】:

我已经启用了约束,因为我不希望数据库处于不良状态,如果数据库有办法防止不良状态,那么我将主要使用它。但是,我希望有一个用户友好的解决方案,我认为它是验证方法,只是返回一个易于解析的异常,而不是检查一个 ef 异常。感谢旁注!尝试过类似的东西,但没有意识到“||”是这样做的方法。

以上是关于实体框架核心存储库模式 - 重复检查的主要内容,如果未能解决你的问题,请参考以下文章

核心数据编码模式

存储库模式和聚合根模式和实体框架

具有存储库模式的实体框架 DAL、BLL

使用实体框架的存储库模式

DAL 中的实体框架存储库模式,如何实现更新功能?

text .NET实体框架核心通用异步操作与工作单元通用存储库