Ошибка миграции EF GetDbProviderManifestToken MySql, как победить?

284
29 октября 2017, 18:14

Делаю в консоли NuGet PM>Enable-Migrations -Force

Ловлю текст Checking if the context targets an existing database... а за тем исключение

System.NullReferenceException: Ссылка на объект не указывает на экземпляр объекта. в MySql.Data.MySqlClient.MySqlProviderServices.GetDbProviderManifestToken(DbConnection connection) в System.Data.Entity.Core.Common.DbProviderServices.GetProviderManifestToken(DbConnection connection) в MySql.Data.Entity.MySqlManifestTokenResolver.ResolveManifestToken(DbConnection connection) в System.Data.Entity.Utilities.DbConnectionExtensions.GetProviderInfo(DbConnection connection, DbProviderManifest& providerManifest) в System.Data.Entity.DbModelBuilder.Build(DbConnection providerConnection) в System.Data.Entity.Internal.LazyInternalContext.CreateModel(LazyInternalContext internalContext) в System.Data.Entity.Internal.RetryLazy 2.GetValue(TInput input) в System.Data.Entity.Internal.LazyInternalContext.InitializeContext()
в System.Data.Entity.Internal.LazyInternalContext.get_ModelBeingInitialized() в System.Data.Entity.Infrastructure.EdmxWriter.WriteEdmx(DbContext context, XmlWriter writer) в System.Data.Entity.Utilities.DbContextExtensions.<>c__DisplayClass1.b__0(XmlWriter w) в System.Data.Entity.Utilities.DbContextExtensions.GetModel(Action`1 writeXml) в System.Data.Entity.Utilities.DbContextExtensions.GetModel(DbContext context) в System.Data.Entity.Migrations.DbMigrator..ctor(DbMigrationsConfiguration configuration, DbContext usersContext, DatabaseExistenceState existenceState, Boolean calledByCreateDatabase) в System.Data.Entity.Migrations.DbMigrator..ctor(DbMigrationsConfiguration configuration) в System.Data.Entity.Migrations.Design.MigrationScaffolder..ctor(DbMigrationsConfiguration migrationsConfiguration) в System.Data.Entity.Migrations.Design.ToolingFacade.ScaffoldRunner.Run() в System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate) в System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate) в System.Data.Entity.Migrations.Design.ToolingFacade.Run(BaseRunner runner) в System.Data.Entity.Migrations.Design.ToolingFacade.ScaffoldInitialCreate(String language, String rootNamespace) в System.Data.Entity.Migrations.EnableMigrationsCommand.<>c__DisplayClass2.<.ctor>b__0() в System.Data.Entity.Migrations.MigrationsDomainCommand.Execute(Action command) Ссылка на объект не указывает на экземпляр объекта.

Пробовал удалять папку Migrations - не помагает. Старые миграции есть, но NuGet консоль их почему-то не видит. Скорее всего прибился migration, он куда-то сохраняет данные о проэкте.

Версии База MySql

EF v 6.0

VS 2017

Как оживить Migrations? Или это проблема самого EF-MySql библиотеки?

Answer 1

Начнём с Configuration.cs

internal sealed class Configuration :   
DbMigrationsConfiguration<MyProj.Domain.Concrete.MysqlEfDbContext> { ...}

Здесь переходим на сам Context

[DbConfigurationType(typeof(MySql.Data.Entity.MySqlEFConfiguration))]
public class MysqlEfDbContext : DbContext
{
    public MysqlEfDbContext() : this("MysqlEfDbContext"/*Строка подключения*/){ }

Особенность, пакет хочет что б для MySql в строка подключения была строка подключения, на en so есть предложение поменять на this("server=127.0.0.1;Database=sys;uid=root;pwd=root;Allow User Variables=True") Но тогда получаем другую интересную "особенность". Код перестаёт нормально функционировать (появляются странные Exceptions), а консоль работает нормально. Что бы выйти из положения, можно написать функцию, которая для web-приложения вернёт алиас, а для консоли - строку подключения. Получилось так:

[DbConfigurationType(typeof(MySql.Data.Entity.MySqlEFConfiguration))]
public class MysqlEfDbContext : DbContext
{    
    public MysqlEfDbContext() :  this(getDBConnectionString("MysqlEfDbContext")) { }
    static string  getDBConnectionString(string connName) {            
        string loc = typeof(MysqlEfDbContext).Assembly.Location;
        string file = getConfigLoc(loc);
            if (!System.IO.File.Exists(file)) {            
            file = loc.Substring(0, loc.LastIndexOf('\\')) + "\\__AssemblyInfo__.ini";                
            using (System.IO.StreamReader rd = new System.IO.StreamReader(file, System.Text.Encoding.Unicode)) file = rd.ReadToEnd();
            if (!(file = file.Split('\0')[1].Replace("file:///", "")).Contains("inetpub")) file = getConfigLoc(file);
            else return connName; // Случай когда Web публикация
        }               
        System.Xml.XmlDocument doc = new System.Xml.XmlDocument();            
        doc.Load( file);
        System.Xml.XmlNode node = doc.SelectSingleNode(string.Format("/configuration/connectionStrings/add[@name='{0}']/@connectionString", connName));            
        return (node == null) ? "" : node.InnerText;           
       }
    static string getConfigLoc(string location) {
        List<string> dirs = new List<string>(location.Split("\\/".ToCharArray()));
        return string.Join("\\", dirs.GetRange(0, dirs.Count - 4).ToArray()) 
    + "\\MyProj.WebUI\\web.config"; // Добавить папку Web-Приложения
    }

Откатал и в работе, и три команды NuGet консоли (или Pkgmgr.exe): Enable-Migrations Add-Migration "Название", Update-Database Работают.

P.S. Ещё у меня возник странный Еxception при Update-Database

System.Runtime.Serialization.SerializationException: Не разрешен тип члена "MySql.Data.MySqlClient.MySqlException,MySql.Data, Version=7.0.2.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d".
в System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate) в System.Data.Entity.Migrations.Design.ToolingFacade.Run(BaseRunner runner) в System.Data.Entity.Migrations.Design.ToolingFacade.Update(String targetMigration, Boolean force) в System.Data.Entity.Migrations.UpdateDatabaseCommand.<>c__DisplayClass2.<.ctor>b__0() в System.Data.Entity.Migrations.MigrationsDomainCommand.Execute(Action command) Не разрешен тип члена "MySql.Data.MySqlClient.MySqlException,MySql.Data, Version=7.0.2.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d".

В этом случае, рекомендую использовать Update-Database -Verbose, тогда понятно, что последняя sql-команда вызвала исключение, тогда нужно смотреть на базу данных - исправить ошибку меняя код процедур Up (реже Down() в миграциях (папка Migrations).

READ ALSO
oracle dblink перестает работать с опцией allow big result sets (odbc mysql connect)

oracle dblink перестает работать с опцией allow big result sets (odbc mysql connect)

Allow big result sets - опция разрешает большие наборы данных, нужна для передачи clob полейЕсли опция не установлена данные будут усечены до 255 символов

296
Есть ли такая почта уже в таблице mySQL

Есть ли такая почта уже в таблице mySQL

Необходимо добавить в код условиеЕсли такая почта уже есть в таблице, то выдать ошибку "E-Mail адрес занят"

225
Скрипт не выполняется

Скрипт не выполняется

На локальной машине тестирую вот этот скрипт

187