【问题标题】:entity framework core exception handling db first实体框架核心异常处理db first
【发布时间】:2017-08-09 20:50:10
【问题描述】:

背景
使用 ef 核心代码优先方法,验证既健壮又简单:https://docs.microsoft.com/en-us/aspnet/core/tutorials/first-mvc-app/validation

使用数据库优先方法,当调用dbcontext.SaveChanges(); 时,数据库似乎正在后台进行任何验证。更糟糕的是,这些异常是模糊不清的,完全没有帮助,例如,如果 any 实体的 any 字符串属性有太多字符 ( ours 是一个充满char(10) 之类的遗留应用程序),或者即使作为字符串的键为空。

问题
我想知道是否有任何合理或可接受的方式来执行验证。我发现 this question 可能有助于调试,但我想在代码中强制执行约束

有没有比将每个自动属性更改为不满足约束时抛出的更好的方法?

【问题讨论】:

    标签: .net-core entity-framework-core


    【解决方案1】:

    EntityFramework Core 根本不强制执行任何验证。您在示例中看到的验证规则由 MVC 而非 EF 强制执行。 EF Core 删除验证检查的主要原因之一是仅此而已。验证在 UI 中运行,然后在 EF 中运行,然后在数据库中再次运行,这只是多余的。因此客户端验证留给前端(在本例中为 MVC),服务器端由数据库引擎完成。

    当您使用数据库优先方法时,EF 核心不会生成任何用于验证的注释,因为它不会对它们进行推理。这意味着您只会获得服务器端验证,这意味着在 SaveChanges 期间会出错。

    在代码(客户端)中强制执行约束的唯一方法是编写这些注释,以便 MVC 可以强制执行它们或编写自定义代码来处理它。整个验证机制对 EF 是透明的。

    【讨论】:

    • 但是我们正在通过 http 数据库 api 编写一个 json-rpc 来替换我们旧的存储过程架构,而不是一个网站。所以重点仍然是 sqlserver 的验证错误消息完全没有价值,我需要一个解决方案,比如扩展代码生成工具以自动添加验证
    • 无论是否是网站,您提供 API 的框架都在进行验证,因为 EF 不会。由于代码中的验证是业务逻辑,因此从数据库中推断它们并不容易,因此数据库首先不会自行生成它们。您可以在从数据库生成模型后编写额外的代码,也可以尝试修改 EF 核心中的代码编写器。虽然前者会容易得多。
    • 主要是我担心的约束类型是数据库中的 char(10) 之类的东西,但属性只是字符串,所以从数据库中推断出这些类型很简单,但是我想我需要自己添加它
    • 您可以对生成的代码使用数据注释,这可以帮助某些情况,例如nvarchar(10) 实际上会为StringLength(10) 注释提供支架。但最终,逻辑因每个客户而异。一旦你开始添加一些验证脚手架,人们就会要求包含越来越多的逻辑,这些逻辑很容易变成复杂的功能。而所有这些,当 EF 实际上根本不尊重这些验证时。
    • 外部库是个不错的主意,它可以扩展 EF 的代码生成并为客户提供挂钩以提供逻辑和脚手架验证注释。
    【解决方案2】:

    我最终对生成器工具进行了伪扩展。由于 DBContext 是一个部分类,我创建了一个新类,它有一个 main

    public partial class DBContext{
        public static void Main(string[]args){
            DBContext context = new DBContext();
            var modelbuilder = new Microsoft.EntityFrameworkCore.ModelBuilder(new Microsoft.EntityFrameworkCore.Metadata.Conventions.ConventionSet());
            context.OnModelCreating(modelbuilder);
            IMutableModel model=modelbuilder.Model;
    

    从那里我使用 Linq 将有关每个实体属性的各种信息及其上的注释转换为 List<KeyValuePair<string,List<KeyValuePair<Regex,string>>>> 其中第一对的键是实体名称,值是查找和替换对的列表以编辑已使用相应验证生成的代码,每个属性一个。然后我所要做的就是滥用工具在<className>.cs 文件中生成类的事实,并遍历我的列表,为每个实体源代码文件执行替换。

    我宁愿做一些不那么 hacky 的事情,因为我依赖 ef 工具输出的格式,但它可以工作

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-16
      • 2021-07-14
      相关资源
      最近更新 更多