最近将现有数据库底层orm切换到ef core,程序也用.net 7开发,于是将数据库对应表生成实体,使用Scaffold-DbContext命令时出现“报证书链是由不受信任的颁发机构颁发的”的错误,出现这个错误的原因是高版本的SQL Server数据库增强了安全功能,通信必须使用安全信道才能建立合法链接,具体的微软官方有说明。
证书链是由不受信任的颁发机构颁发的
执行的命令为:
Scaffold-DbContext -Provider Microsoft.EntityFrameworkCore.SqlServer -Connection "Password=https://jhrs.com;Persist Security Info=True;User ID=sa;Initial Catalog=znlive_com_db;Data Source=www.znlive.com;MultipleActiveResultSets=true;Max Pool Size=512; Min Pool Size=20;timeout=3000;"
按照以前使用ef core的常规操作执行Scaffold-DbContext命令来逆向生成实体类(数据库已经存在了,或者叫DB first吧),高版本的SqlServer数据库不出意外会出现如下图所示的错误:
详细的错误内容为:
Microsoft.Data.SqlClient.SqlException (0x80131904): A connection was successfully established with the server, but then an error occurred during the login process. (provider: SSL Provider, error: 0 - 证书链是由不受信任的颁发机构颁发的。) ---> System.ComponentModel.Win32Exception (0x80090325): 证书链是由不受信任的颁发机构颁发的。 at Microsoft.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection) at Microsoft.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal& connection) at Microsoft.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection) at Microsoft.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions) at Microsoft.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions) at Microsoft.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry, SqlConnectionOverrides overrides) at Microsoft.Data.SqlClient.SqlConnection.Open(SqlConnectionOverrides overrides) at Microsoft.Data.SqlClient.SqlConnection.Open() at Microsoft.EntityFrameworkCore.SqlServer.Scaffolding.Internal.SqlServerDatabaseModelFactory.Create(DbConnection connection, DatabaseModelFactoryOptions options) at Microsoft.EntityFrameworkCore.SqlServer.Scaffolding.Internal.SqlServerDatabaseModelFactory.Create(String connectionString, DatabaseModelFactoryOptions options) at Microsoft.EntityFrameworkCore.Scaffolding.Internal.ReverseEngineerScaffolder.ScaffoldModel(String connectionString, DatabaseModelFactoryOptions databaseOptions, ModelReverseEngineerOptions modelOptions, ModelCodeGenerationOptions codeOptions) at Microsoft.EntityFrameworkCore.Design.Internal.DatabaseOperations.ScaffoldContext(String provider, String connectionString, String outputDir, String outputContextDir, String dbContextClassName, IEnumerable`1 schemas, IEnumerable`1 tables, String modelNamespace, String contextNamespace, Boolean useDataAnnotations, Boolean overwriteFiles, Boolean useDatabaseNames, Boolean suppressOnConfiguring, Boolean noPluralize) at Microsoft.EntityFrameworkCore.Design.OperationExecutor.ScaffoldContextImpl(String provider, String connectionString, String outputDir, String outputDbContextDir, String dbContextClassName, IEnumerable`1 schemaFilters, IEnumerable`1 tableFilters, String modelNamespace, String contextNamespace, Boolean useDataAnnotations, Boolean overwriteFiles, Boolean useDatabaseNames, Boolean suppressOnConfiguring, Boolean noPluralize) at Microsoft.EntityFrameworkCore.Design.OperationExecutor.ScaffoldContext.<>c__DisplayClass0_0.<.ctor>b__0() at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__DisplayClass3_0`1.<Execute>b__0() at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action) ClientConnectionId:59d9c3ad-7697-4e87-bb4a-9fb34f474390 Error Number:-2146893019,State:0,Class:20 A connection was successfully established with the server, but then an error occurred during the login process. (provider: SSL Provider, error: 0 - 证书链是由不受信任的颁发机构颁发的。)
造成这个错误的原因:
当尝试使用不可验证的证书与 SQL Server 建立加密连接时,会发生此错误。 这可能会发生在以下场景中:
应用场景 | 服务器端加密 | 客户端加密 | 证书类型 | 受信任的根证书颁发机构存储中的证书颁发机构 |
---|---|---|---|---|
1 | 是 | 否 | 从非受信任源预配证书 (证书颁发机构未在客户端计算机上的受信任根证书颁发机构中列为受信任的颁发机构) | 否 |
2 | 关 | 是 | SQL Server 自生成证书 | 自签名证书不会显示在此存储中。 |
在建立与 SQL Server 的加密连接时,安全通道 (Schannel) 通过搜索本地计算机上的受信任的根证书颁发机构存储来创建受信任的证书颁发机构列表。 在 TLS 握手期间,服务器会将其公钥证书发送到客户端。 公钥证书的颁发者称为证书颁发机构 (CA)。 客户端必须确保证书颁发机构是客户端信任的证书颁发机构之一。 这是通过提前知晓受信任 CA 的公钥来实现的。 当 Schannel 检测到由不受信任的证书颁发机构颁发的证书(如上述两种情况)时,会收到症状部分中列出的错误消息。
如何解决?
我只是想把数据库里面的表逆向生成实体类而已,要解决这个问题,只需要在连接字符串上动动手脚就可以了,将原来的数据库连接:
Scaffold-DbContext -Provider Microsoft.EntityFrameworkCore.SqlServer -Connection "Password=https://jhrs.com;Persist Security Info=True;User ID=sa;Initial Catalog=znlive_com_db;Data Source=www.znlive.com;MultipleActiveResultSets=true;Max Pool Size=512; Min Pool Size=20;timeout=3000;"
修改为:
Scaffold-DbContext -Provider Microsoft.EntityFrameworkCore.SqlServer -Connection "Password=https://jhrs.com;Persist Security Info=True;User ID=sa;Initial Catalog=znlive_com_db;Data Source=www.znlive.com;MultipleActiveResultSets=true;Max Pool Size=512; Min Pool Size=20;timeout=3000;Encrypt=True;TrustServerCertificate=True;" -OutputDir Entities //注意:上面使用 -OutputDir Entities 参数指定了逆向生成的实体类文件保存目录
也就是说只需要在原来数据库连接上面加上:;Encrypt=True;TrustServerCertificate=True; 就可以了,这样我们就可以很愉快的逆向数据库表为实体对象了。
最终生成的文件也会如期的保存到我们使用 outputdir参数指定的目录,点击这里查看更多的 ef core教程。
Scaffold-DbContext命令实用参数说明
已经存在的数据库要使用ef core,你需要进行逆向工程,这是基于数据库架构搭建实体类型类和 DbContext 类基架的过程。 可使用 EF Core 包管理器控制台 (PMC) 工具的 Scaffold-DbContext
命令或 .NET 命令行接口 (CLI) 工具的 dotnet ef dbcontext scaffold
命令执行这一过程。
先决条件
- 在进行反向工程之前,需要安装 PMC 工具(仅限 Visual Studio)或 CLI 工具。 有关详细信息,请参阅链接。
- 在要搭建基架的项目中安装
Microsoft.EntityFrameworkCore.Design
的 NuGet 包。 - 还需要为要进行反向工程的数据库架构安装适当的数据库提供程序。
指定表
默认情况下,将数据库架构中的所有表反向工程为实体类型。 可通过指定架构和表来限制对哪些表进行反向工程。
--schema
选项可用于包含架构中的每个表,而 --table
可用于包含特定表。若要包含多个表,请多次指定选项:
dotnet ef dbcontext scaffold ... --table jhrscom --table znlivecom
保留名称
默认情况下,表和列名已修正,以便更好地匹配类型和属性的 .NET 命名约定。 在 PMC 中指定 -UseDatabaseNames
开关或在 .NET Core CLI 中指定 --use-database-names
选项将禁用此行为,从而尽可能保留原始数据库名称。 无效的 .NET 标识符仍将被修正,而合成名称(如导航属性)仍将符合 .NET 命名约定。
Fluent API 和数据注释
默认情况下,使用 Fluent API 配置实体类型。 指定 -DataAnnotations
(PMC) 或 --data-annotations
(.NET Core CLI) 以改为使用数据注释(如果可能)。
例如,使用 Fluent API 将搭建以下项的基架:
entity.Property(e => e.Title) .IsRequired() .HasMaxLength(160);
而使用数据注释则将搭建以下项的基架:
[Required] [StringLength(160)] public string Title { get; set; }
目录和命名空间
实体类和 DbContext 类将搭建到项目的根目录中,并使用项目的默认命名空间。可使用 --output-dir
指定在其中为类搭建基架的目录,并且可使用 --context-dir
将 DbContext 类搭建到与实体类型类不同的目录中:
dotnet ef dbcontext scaffold ... --context-dir Data --output-dir Models
默认情况下,命名空间将是根命名空间加上项目根目录下任何子目录的名称。 但是,从 EFCore 5.0 开始,可使用 --namespace
覆盖所有输出类的命名空间。 还可使用 --context-namespace
仅覆盖 DbContext 类的命名空间:
dotnet ef dbcontext scaffold ... --namespace Your.Namespace --context-namespace Your.DbContext.Namespace
【江湖人士】(jhrs.com)原创文章,作者:江小编,如若转载,请注明出处:https://jhrs.com/2022/46032.html
扫码加入电报群,让你获得国外网赚一手信息。