2014-11-21 110 views
3

虽然在Mono上使用包含实体框架的PostgreSQL数据库NpsqlNpsql.EntityFramework当尝试从控制台运行Code First迁移时遇到异常。应用程序的连接并在应用程序运行和数据库可通过编程方式CRUD'ed如何禁用MARS并规避“MARS尚未实现”-exception“?

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<T>派生的类配置如下:

public class Configuration : DbMigrationsConfiguration<ZkContext> 
{ 
    public Configuration() 
    { 
     AutomaticMigrationsEnabled = false; 
     SetSqlGenerator("Npgsql", new PostgreSqlMigrationSqlGenerator()); 
    } 
} 

PostgreSqlMigrationSqlGenerator类来自this PostgreSqlMigrationSqlGenerator repository(同样的错误弹出与默认SqlGenerator,使代码不是问题)。

我尝试从一个控制台应用程序运行配置通过this idea,这是可能的,因为PowerShell命令“只是薄包装在底层API”如下:

var config = new Configuration(); 
var scaffolder = new MigrationScaffolder(config); //<= Here it breaks 
var migration = scaffolder.Scaffold("Initial"); 

不幸的是,添加MigrationScaffolder(config)声明此错误弹出:

System.NotImplementedException已被抛出。 MARS尚未实施!

多活动结果集(MARS)显然还没有在Mono中实现。 Mono框架中的类System.Data.SqlClient.SqlConnectionStringBuilder负责。如果你遵循的链接代码,你可以看到,line 797抛出异常:

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 (string key, object value)方法。

我的问题是:有没有办法把MARS关闭,并让迁移生成器不抛出异常?

/编辑将;MultipleActiveResultSets=False附加到连接字符串不起作用,因为它不是PostgreSQL连接字符串的有效属性。此外,在ZkContext上下文类中设置Configuration.LazyLoadingEnabled = false;也无济于事。

/编辑调用堆栈:

System.Data.SqlClient.SqlConnectionStringBuilder.SetValue(键= “multipleactiveresultsets”,值= “真”)的 System.Data.SqlClient.SqlConnectionStringBuilder.set_Item(关键字)
System.Data中的 System.Data.Common.DbConnectionStringBuilder.ParseConnectionStringNonOdbc(connectionString =“Data Source =。\ SQLEXPRESS; Integrated Security = True; MultipleActiveResultSets = True;”)=“multipleactiveresultsets”,value =“True” .Common.DbConnectionStringBuilder.ParseConnectionString(connectionString =“Data
S乌尔斯河= \ SQLEXPRESS。集成安全性=真; MultipleActiveResultSets = True;“
)in
System.Data.Common.DbConnectionStringBuilder.set_ConnectionString(value =”Data
Source =。\ SQLEXPRESS;集成安全性=真; MultipleActiveResultSets = TRUE; “在
System.Data.SqlClient.SqlConnectionStringBuilder..ctor(的connectionString =)” 数据
源= \ SQLEXPRESS;集成安全性= TRUE; MultipleActiveResultSets =真;“)中
System.Data.Entity的.Infrastructure.SqlConnectionFactory.CreateConnection

System.Data.Entity.Internal.LazyInternalConnection.Initialize()在
System.Data.Entity.Internal.LazyInternalConnection.get_Connection()在
系统(nameOrConnectionString = “ZkTestDatabaseConnection”) .Data.Entity.Internal.LazyInternalContext.get_Connection()in
System.Data.Entity.Infrastructure.DbContex tInfo..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})
System.Data.Entity.Migrations.DbMigrator..ctor(configuration =
{Zk.Migrations.Configuration},usersContext =(null),
existsState = System.Data.Entity。 Internal.DatabaseExistenceState.Unknown,
calledByCreateDatabase = false)
System.Data.Entity.Migrations.DbMigrator..ctor(配置=
{Zk.Migrations.Configuration})在
System.Data.Entity.Migrations.Design.MigrationScaffolder..ctor(migrationsConfiguration =
{Zk.Migrations .Configuration})在
Zk.Migrations.MigrationsTool.Main(参数= {串[0]})在/ home /欧文/ zaaikalender
/Zk.Migrations/MigrationsTool.cs:23

的粗体连接字符串不是指定的连接字符串。

+0

注:.NET将会跨平台和开源的;所以没有更多的单声道!虽然今天可能不会帮助你*。 – BradleyDotNET 2014-11-21 20:21:30

+0

那么这将是Mono和.NET之间的合作,而不是重建。由于.NET核心现在是开源的,微软将在Mono紧密合作的情况下为Mono提供全面支持,因此可以更轻松地修复和实施错误和缺失功能。 /编辑更正:似乎Mono和.NET将保持分离? ([来源](http://www.theregister.co.uk/2014/11/12/release_microsoft_net_from_its_windows_chains_mono_and_xamarin_guy_miguel_de_icaza_on_open_source_net/))。无论如何,也许你会看到如何不进入上面的Case语句?:-) – 2014-11-21 20:30:53

+0

只是检查显而易见的 - 你有连接字符串配置中的'MultipleActiveResultSets'设置吗? – Rhumborl 2014-11-21 20:33:00

回答

2

没有必要禁用MARS。从显式堆栈跟踪中可以看出,我的上下文使用了默认的连接字符串。发生这种情况是因为我在控制台应用程序中从单独的项目运行迁移。

当我复制了一些在默认的项目(其中DbContext居住)的web.config的信息发送到控制台的app.config应用程式编写的建设者。

迁移正在工作(!)和MARS错误不再发生,因为现在正确的连接字符串被采用。在迁移项目的app.config

复制的XML配置:

<?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>