问题描述
在使用 PostgreSQL 数据库和 Mono 上的实体框架时使用包 Npsql
和 Npsql.EntityFramework
我尝试从控制台应用程序运行 Code First 迁移时出现异常.该连接在应用程序中确实有效,并且可以通过编程方式对数据库进行 CRUD.
While using a PostgreSQL database with Entity Framework on Mono using the packages Npsql
and Npsql.EntityFramework
I get an exception while trying to run Code First migrations from a Console app. The connection does work in the app and the database can be CRUD'ed programmatically.
Context
类如下所示:
public class ZkContext : DbContext, IZkContext
{
public ZkContext() : base("ZkTestDatabaseConnection")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// PostgreSQL uses schema public by default.
modelBuilder.HasDefaultSchema("public");
}
public IDbSet<Crop> Crops { get; set; }
}
此外,还有一个派生自 DbMigrationsConfiguration
的类 Configuration,如下所示:
Furthermore, there is a class Configuration that derives from DbMigrationsConfiguration<T>
as follows:
public class Configuration : DbMigrationsConfiguration<ZkContext>
{
public Configuration ()
{
AutomaticMigrationsEnabled = false;
SetSqlGenerator("Npgsql", new PostgreSqlMigrationSqlGenerator());
}
}
PostgreSqlMigrationSqlGenerator
类来自这个 PostgreSqlMigrationSqlGenerator 存储库(同样的错误弹出默认的 SqlGenerator,这样代码就不是问题了).
The PostgreSqlMigrationSqlGenerator
class comes from this PostgreSqlMigrationSqlGenerator repository (the same error pops up with the default SqlGenerator so that code is not the problem).
我尝试通过 这个想法从控制台应用程序运行配置,如下所示,这是可能的,因为 PowerShell 命令只是底层 API 的瘦包装器":
I try to run the configuration from a console app as follows via this idea, which is possible since the PowerShell commands "are just thin wrappers over an underlying API":
var config = new Configuration();
var scaffolder = new MigrationScaffolder(config); //<= Here it breaks
var migration = scaffolder.Scaffold("Initial");
不幸的是,添加 MigrationScaffolder(config)
语句会弹出此错误:
Unfortunately, add the MigrationScaffolder(config)
statement this error pops up:
System.NotImplementedException 已被抛出.MARS 尚未实施!
System.NotImplementedException has been thrown. MARS is not yet implemented!
Multiple Active Result Sets (MARS) 显然还没有在 Mono 中实现.类 System.Data.SqlClient.SqlConnectionStringBuilder
在 Mono 框架中负责.如果您点击代码链接,您可以看到在 line 797
上抛出了异常:
Multiple Active Result Sets (MARS) are apparently not implemented in Mono yet. The class System.Data.SqlClient.SqlConnectionStringBuilder
in the Mono framework is responsible. If you follow the link to the code you can see that on line 797
the exception is thrown:
case "MULTIPLEACTIVERESULTSETS":
if (value == null) {
_multipleActiveResultSets = DEF_MULTIPLEACTIVERESULTSETS;
base.Remove (mappedKey);
} else if ( DbConnectionStringBuilderHelper.ConvertToBoolean (value))
throw new NotImplementedException ("MARS is not yet implemented!");
break;
在SetValue(字符串键,对象值)
方法中.
我的问题是:有没有办法关闭 MARS 并让迁移生成器不抛出异常?
/edit 将 ;MultipleActiveResultSets=False
附加到连接字符串没有帮助,因为它不是 PostgreSQL 连接字符串的有效属性.此外,在 ZkContext
上下文类上设置 Configuration.LazyLoadingEnabled = false;
也无济于事.
/edit Appending ;MultipleActiveResultSets=False
to the connection string does not help since it is not a valid property for PostgreSQL connection strings. Furthermore, setting Configuration.LazyLoadingEnabled = false;
on the ZkContext
context class does not help either.
/edit 调用栈:
System.Data.SqlClient.SqlConnectionStringBuilder.SetValue (key="multipleactiveresultsets", value="True") 在System.Data.SqlClient.SqlConnectionStringBuilder.set_Item (keyword="multipleactiveresultsets", value="True") 在System.Data.Common.DbConnectionStringBuilder.ParseConnectionStringNonOdbc (connectionString="Data Source=.SQLEXPRESS; Integrated Security=True; MultipleActiveResultSets=True;") 在
System.Data.Common.DbConnectionStringBuilder.ParseConnectionString (connectionString="Data
Source=.SQLEXPRESS; Integrated Security=True; MultipleActiveResultSets=True;") in
System.Data.Common.DbConnectionStringBuilder.set_ConnectionString (value="Data
Source=.SQLEXPRESS; Integrated Security=True; MultipleActiveResultSets=True;") in
System.Data.SqlClient.SqlConnectionStringBuilder..ctor (connectionString="Data
Source=.SQLEXPRESS; Integrated Security=True; MultipleActiveResultSets=True;") in
System.Data.Entity.Infrastructure.SqlConnectionFactory.CreateConnection
(nameOrConnectionString="ZkTestDatabaseConnection") in
中的System.Data.Entity.Internal.LazyInternalConnection.Initialize()System.Data.Entity.Internal.LazyInternalConnection.get_Connection() in
中的System.Data.Entity.Internal.LazyInternalContext.get_Connection()System.Data.Entity.Infrastructure.DbContextInfo..ctor (contextType={Zk.Models.ZkContext},
modelProviderInfo=(null), config={System.Data.Entity.Internal.AppConfig},
connectionInfo=(null), resolver=(null)) 在
System.Data.Entity.Infrastructure.DbContextInfo..ctor (contextType={Zk.Models.ZkContext},
resolver=(null)) in
中的 System.Data.Entity.Infrastructure.DbContextInfo..ctor (contextType={Zk.Models.ZkContext})System.Data.Entity.Migrations.DbMigrator..ctor (configuration=
{Zk.Migrations.Configuration}, usersContext=(null),
existenceState=System.Data.Entity.Internal.DatabaseExistenceState.Unknown,
calledByCreateDatabase=false) 在
中的 System.Data.Entity.Migrations.DbMigrator..ctor (configuration=
{Zk.Migrations.Configuration})System.Data.Entity.Migrations.Design.MigrationScaffolder..ctor (migrationsConfiguration=
{Zk.Migrations.Configuration}) 在
Zk.Migrations.MigrationsTool.Main (args={string[0]}) 在/home/erwin/zaaikalender
/Zk.Migrations/MigrationsTool.cs:23
System.Data.SqlClient.SqlConnectionStringBuilder.SetValue (key="multipleactiveresultsets", value="True") in System.Data.SqlClient.SqlConnectionStringBuilder.set_Item (keyword="multipleactiveresultsets", value="True") in System.Data.Common.DbConnectionStringBuilder.ParseConnectionStringNonOdbc (connectionString="Data Source=.SQLEXPRESS; Integrated Security=True; MultipleActiveResultSets=True;") in
System.Data.Common.DbConnectionStringBuilder.ParseConnectionString (connectionString="Data
Source=.SQLEXPRESS; Integrated Security=True; MultipleActiveResultSets=True;") in
System.Data.Common.DbConnectionStringBuilder.set_ConnectionString (value="Data
Source=.SQLEXPRESS; Integrated Security=True; MultipleActiveResultSets=True;") in
System.Data.SqlClient.SqlConnectionStringBuilder..ctor (connectionString="Data
Source=.SQLEXPRESS; Integrated Security=True; MultipleActiveResultSets=True;") in
System.Data.Entity.Infrastructure.SqlConnectionFactory.CreateConnection
(nameOrConnectionString="ZkTestDatabaseConnection") in
System.Data.Entity.Internal.LazyInternalConnection.Initialize () in
System.Data.Entity.Internal.LazyInternalConnection.get_Connection () in
System.Data.Entity.Internal.LazyInternalContext.get_Connection () in
System.Data.Entity.Infrastructure.DbContextInfo..ctor (contextType={Zk.Models.ZkContext},
modelProviderInfo=(null), config={System.Data.Entity.Internal.AppConfig},
connectionInfo=(null), resolver=(null)) in
System.Data.Entity.Infrastructure.DbContextInfo..ctor (contextType={Zk.Models.ZkContext},
resolver=(null)) in
System.Data.Entity.Infrastructure.DbContextInfo..ctor (contextType={Zk.Models.ZkContext}) in
System.Data.Entity.Migrations.DbMigrator..ctor (configuration=
{Zk.Migrations.Configuration}, usersContext=(null),
existenceState=System.Data.Entity.Internal.DatabaseExistenceState.Unknown,
calledByCreateDatabase=false) in
System.Data.Entity.Migrations.DbMigrator..ctor (configuration=
{Zk.Migrations.Configuration}) in
System.Data.Entity.Migrations.Design.MigrationScaffolder..ctor (migrationsConfiguration=
{Zk.Migrations.Configuration}) in
Zk.Migrations.MigrationsTool.Main (args={string[0]}) in /home/erwin/zaaikalender
/Zk.Migrations/MigrationsTool.cs:23
粗体连接字符串不是指定的连接字符串.
The bold connection string is not the specified connection string.
推荐答案
没有必要禁用 MARS.从显式堆栈跟踪中可以看出,我的上下文使用了默认连接字符串.发生这种情况是因为我在控制台应用程序中从 separate 项目运行迁移.
It was not necessary to disable MARS. What can be seen from the explicit stack trace is that my context used a default connection string. This happened because I was running migrations from a separate project in a console app.
当我将默认项目的 web.config
中的一些信息(DbContext
所在的位置)复制到 app.config
构建器编译的控制台应用程序.
When I copied some of the information in the web.config
of the default project (where the DbContext
resided) to the app.config
of the console app the builder compiled.
迁移正在运行 (!) 并且 MARS 错误不再发生,因为现在采用了正确的连接字符串.
The migrations are working (!) and the MARS error does not happen any more since the correct connection string is now taken.
迁移项目的 app.config
中的重复 xml 配置:
Duplicated xml-configuration in app.config
of migrations project:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="entityFramework"
type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.1.1, Culture=neutral, PublicKeyToken=b77a5c561934e089"
requirePermission="false" />
</configSections>
<!-- <connectionStrings configSource="../Zk/ConnectionStrings.config" /> -->
<connectionStrings>
<clear />
<add name="ZkTestDatabaseConnection"
connectionString="Server=localhost;Port=5432;Database=ZkTestDatabase;User Id=zktest;Password=broccoli;CommandTimeout=20;"
providerName="Npgsql" />
</connectionStrings>
<system.data>
<DbProviderFactories>
<add name="Npgsql Data Provider"
invariant="Npgsql"
description="Data Provider for PostgreSQL"
type="Npgsql.NpgsqlFactory, Npgsql" />
</DbProviderFactories>
</system.data>
<entityFramework>
<defaultConnectionFactory type="Npgsql.NpgsqlFactory, Npgsql" />
<providers>
<provider invariantName="Npgsql"
type="Npgsql.NpgsqlServices, Npgsql.EntityFramework" />
</providers>
</entityFramework>
</configuration>
这篇关于如何禁用 MARS 并规避“MARS 尚未实现"-异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!