0

У меня было решение с EF5 + Migrations с двумя базами данных SqlServer/SqlCe4. У меня есть код в коде для установки соответствующих соединений. Все прошло отлично.EF6 + Migrations + SqlServer/SqlCe4

Но теперь мне нужны некоторые функции EF6, поэтому я обновил их. Первоначально он работал с SqlServer, но у меня были серьезные проблемы с SqlCe. Ошибка: «Указанная таблица уже существует [TableName].»

Сейчас он не работает ни с одной из них: «Указанный индекс уже существует [IX_TableNameId]»

Связи создаются на заводе :

public static class ContextFactory 
{ 
    static ContextFactory() 
    { 
     Database.SetInitializer(new MigrateDatabaseToLatestVersion<SongServiceDataContext, SongServiceConfiguration>()); 
    } 

    public static SongServiceDataContext GetClientContext() 
    { 
     // Get path 
     var path = ConfigurationManager.AppSettings["LocalDbPath"]; 

     // Create SqlCe connection 
     var sb = new SqlCeConnectionStringBuilder { DataSource = path }; 
     var con = new SqlCeConnection(sb.ToString()); 

     return new SongServiceDataContext(con); 
    } 

    public static SongServiceDataContext GetServerContext() 
    { 
     // Get connectionstring 
     var connectionString = ConfigurationManager.AppSettings["ServerConnectionString"]; 
     if (!connectionString.IsSpecified()) 
      throw new Exception("AppSetting 'ServerConnectionString' must be specified in config file"); 

     // Create SqlServer connection 
     var sb = new SqlConnectionStringBuilder(connectionString); 
     var con = new SqlConnection(sb.ToString()); 

     return new SongServiceDataContext(con); 
    } 
} 

Я решил удалить базы данных и перезапустить миграцию с помощью первоначального создания. Add-Migration InitalModel -ProjectName: "MyApp.Business" Это вызывает следующую ошибку:

System.ArgumentException: The ADO.NET provider with invariant name 'v11.0' is either not registered in the machine or application config file, or could not be loaded. See the inner exception for details. ---> System.ArgumentException: Unable to find the requested .Net Framework Data Provider. It may not be installed. 
    at System.Data.Common.DbProviderFactories.GetFactory(String providerInvariantName) 
    at System.Data.Entity.Infrastructure.DependencyResolution.DefaultProviderFactoryResolver.GetService(Type type, Object key, Func`3 handleFailedLookup) 
    --- End of inner exception stack trace --- 
    at System.Data.Entity.Infrastructure.DependencyResolution.DefaultProviderFactoryResolver.<GetService>b__0(ArgumentException e, String n) 
    at System.Data.Entity.Infrastructure.DependencyResolution.DefaultProviderFactoryResolver.GetService(Type type, Object key, Func`3 handleFailedLookup) 
    at System.Data.Entity.Infrastructure.DependencyResolution.DefaultProviderFactoryResolver.GetService(Type type, Object key) 
    at System.Data.Entity.Infrastructure.DependencyResolution.CachingDependencyResolver.<>c__DisplayClass1.<GetService>b__0(Tuple`2 k) 
    at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory) 
    at System.Data.Entity.Infrastructure.DependencyResolution.CachingDependencyResolver.GetService(Type type, Object key) 
    at System.Data.Entity.Infrastructure.DependencyResolution.ResolverChain.<>c__DisplayClass3.<GetService>b__0(IDbDependencyResolver r) 
    at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() 
    at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source, Func`2 predicate) 
    at System.Data.Entity.Infrastructure.DependencyResolution.ResolverChain.GetService(Type type, Object key) 
    at System.Data.Entity.Infrastructure.DependencyResolution.RootDependencyResolver.GetService(Type type, Object key) 
    at System.Data.Entity.Infrastructure.DependencyResolution.ResolverChain.<>c__DisplayClass3.<GetService>b__0(IDbDependencyResolver r) 
    at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() 
    at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source, Func`2 predicate) 
    at System.Data.Entity.Infrastructure.DependencyResolution.ResolverChain.GetService(Type type, Object key) 
    at System.Data.Entity.Infrastructure.DependencyResolution.CompositeResolver`2.GetService(Type type, Object key) 
    at System.Data.Entity.Infrastructure.DependencyResolution.DbDependencyResolverExtensions.GetService[T](IDbDependencyResolver resolver, Object key) 
    at System.Data.Entity.Infrastructure.SqlCeConnectionFactory.CreateConnection(String nameOrConnectionString) 
    at System.Data.Entity.Internal.LazyInternalConnection.Initialize() 
    at System.Data.Entity.Internal.LazyInternalConnection.get_Connection() 
    at System.Data.Entity.Internal.LazyInternalContext.get_Connection() 
    at System.Data.Entity.Infrastructure.DbContextInfo..ctor(Type contextType, DbProviderInfo modelProviderInfo, AppConfig config, DbConnectionInfo connectionInfo, Func`1 resolver) 
    at System.Data.Entity.Migrations.DbMigrator..ctor(DbMigrationsConfiguration configuration, DbContext usersContext, DatabaseExistenceState existenceState, Boolean calledByCreateDatabase) 
    at System.Data.Entity.Migrations.DbMigrator..ctor(DbMigrationsConfiguration configuration) 
    at System.Data.Entity.Migrations.Design.MigrationScaffolder..ctor(DbMigrationsConfiguration migrationsConfiguration) 
    at System.Data.Entity.Migrations.Design.ToolingFacade.ScaffoldRunner.Run() 
    at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate) 
    at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate) 
    at System.Data.Entity.Migrations.Design.ToolingFacade.Run(BaseRunner runner) 
    at System.Data.Entity.Migrations.Design.ToolingFacade.Scaffold(String migrationName, String language, String rootNamespace, Boolean ignoreChanges) 
    at System.Data.Entity.Migrations.AddMigrationCommand.Execute(String name, Boolean force, Boolean ignoreChanges) 
    at System.Data.Entity.Migrations.AddMigrationCommand.<>c__DisplayClass2.<.ctor>b__0() 
    at System.Data.Entity.Migrations.MigrationsDomainCommand.Execute(Action command) 
The ADO.NET provider with invariant name 'v11.0' is either not registered in the machine or application config file, or could not be loaded. See the inner exception for details. 

Это выглядит как ошибка конфигурации, так что я проверил App.config указанного проекта:

<?xml version="1.0" encoding="utf-8"?> 
<configuration> 
    <configSections> 
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /> 
    </configSections> 
    <entityFramework> 
    <providers> 
     <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" /> 
     <provider invariantName="System.Data.SqlServerCe.4.0" type="System.Data.Entity.SqlServerCompact.SqlCeProviderServices, EntityFramework.SqlServerCompact" /> 
    </providers> 
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework"> 
     <parameters> 
     <parameter value="v11.0" /> 
     <parameter value="System.Data.SqlClient" /> 
     <parameter value="System.Data.SqlServerCe.4.0" /> 
     </parameters> 
    </defaultConnectionFactory> 
    </entityFramework> 
</configuration> 

Я попытался изменить все, так что теперь я немного расстроен.

Любая помощь приветствуется.

+0

Похоже, что ваша локальная установка установлена, попробуйте переустановить ее – ErikEJ

+0

Не могу вспомнить, что я когда-либо устанавливал localdb. Будет ли он частью какой-либо другой установки (SQL Server, VS2013, SQLCe4, ...)? Неужели мне это нужно? У меня установлены SQL Server и SqlCe4. Мое намерение с ContextFactory состояло в том, чтобы использовать любой из них. Должен ли я изменить конфигурацию, чтобы генерация миграции использовала что-то еще? –

ответ

1

Ошибки Entity Framework сообщения были очень вводящими в заблуждении. Основная проблема была на самом деле больше на стороне создания контекста. В моем контексте классе у меня было два конструктора, один инициализируются с подключением и один параметром меньше:

public MyDataContext(DbConnection conn): base(conn, true) 
{ 
} 

public MyDataContext() 
{ 
} 

я, наконец, понял, что даже если бы я не звонил параметр меньше конструктора он был на самом деле называется несколько раз по миграции. Это вызывает много путаницы ...

Как я понимаю, правильный путь теперь направлять миграцию в правильном направлении - позволить фабрике контекста реализовать IDbContextFactory. Я попытался вызвать конкретные методы для создания каждого контекста, но миграция по-прежнему вызывала метод IDbContextFactory Create за кулисами. Я не нашел надежного способа решить, какой контекст нужно назвать.

В моей ситуации на самом деле нормально иметь глобальный переключатель, поскольку каждая вызывающая сборка всегда использует один и тот же контекст. Поэтому я решил установить статическое свойство на фабричном классе. Он устанавливается при запуске приложения и затем направляет создание в правильном направлении.

public class ContextFactory : IDbContextFactory<MyDataContext> 
{ 
    public static DbSource DefaultDbSource = DbSource.Client; 

    static ContextFactory() 
    { 
     Database.SetInitializer(new MigrateDatabaseToLatestVersion<SongServiceDataContext, SongServiceConfiguration>()); 
    } 

    /// <summary> 
    /// This is called by the migration. 
    /// </summary> 
    public MyDataContext Create() 
    { 
     return GetContext(); 
    } 

    /// <summary> 
    /// This is added for my convenience. 
    /// </summary> 
    public static MyDataContext GetContext() 
    { 
     return DefaultDbSource == DbSource.Client ? GetClientContext() : GetServerContext(); 
    } 


    #region Private Methods 

    private static MyDataContext GetClientContext() 
    { 
     // Get path 
     var dirDocuments = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); 
     var dirData = Path.Combine(dirDocuments, "MyApplication", "Data"); 
     if (!Directory.Exists(dirData)) 
      Directory.CreateDirectory(dirData); 
     var path = Path.Combine(dirData, "MyApplicationData.sdf"); 

     // Create SqlCe connection 
     var sb = new SqlCeConnectionStringBuilder {DataSource = path}; 
     var con = new SqlCeConnection(sb.ToString()); 

     return new MyDataContext(con); 
    } 

    private static MyDataContext GetServerContext() 
    { 
     // Get connectionstring 
     var connectionString = ConfigurationManager.AppSettings["ServerConnectionString"]; 
     if (!connectionString.IsSpecified()) 
      throw new Exception("AppSetting 'ServerConnectionString' must be specified in config file"); 

     // Create SqlServer connection 
     var sb = new SqlConnectionStringBuilder(connectionString); 
     var con = new SqlConnection(sb.ToString()); 

     return new SongServiceDataContext(con); 
    } 

    #endregion 
} 

Совет. Даже после того, как я установил эту заводскую настройку, у меня были некоторые проблемы. Миграция прошла нормально, но каждое соединение после этого вызывало всевозможные странные проблемы.Я боролся с часами и был близок к тому, чтобы сдаться. Простая чистка и восстановление моего решения сделали последний трюк! Кажется, что остаточные файлы, должно быть, вызвали некоторую путаницу.

0

Раздел:

<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework"> 
    <parameters> 
    <parameter value="v11.0" /> 
    <parameter value="System.Data.SqlClient" /> 
    <parameter value="System.Data.SqlServerCe.4.0" /> 
    </parameters> 
</defaultConnectionFactory> 

полностью нарушена, и несколько secitions для SQLCE отсутствуют в конфигурационном файле.

Создать новое пустое консольное приложение, и установить пакет EntityyFramework.SqlServerCompact, чтобы получить правильные настройки конфигурации

+0

Спасибо Эрик, простой и полезный совет! Теперь мне снова удалось запустить миграцию. Но когда я на самом деле вызываю базы данных, такая же запутанная ошибка снова возникает: «Указанная таблица уже существует. [ObjectName]». Я получаю то же сообщение для SqlCe и SqlServer. Ни клиентская, ни серверная база данных не генерируются. Датамодел должен быть в порядке, так как он отлично работал до обновления до EF6 .... –

Смежные вопросы