Код Entity Framework сначала вызывает исключение при доступе к базе данных

Недавно начал пытаться разобраться с первым подходом к коду для Entity Framework. Я создал несколько таблиц базы данных, следуя различным руководствам, но ни один из них не помог.

Начиная с нуля примерно 3-4 раза, потому что исключения становятся все более и более абсурдными. В прошлый раз база данных была создана при первом доступе, но не удалось подключиться к базе данных во втором сеансе отладки из-за отсутствия разрешений (используя встроенную систему безопасности — что?). По-видимому, .mdf был заблокирован системным процессом, и только перезагрузка в безопасном режиме позволила мне избавиться от него.

Во всяком случае, заново. У меня есть библиотека классов, которая содержит модели баз данных и класс шлюза для внешнего доступа. У меня есть консольный проект для проверки создания базы данных и доступа к ней. EF устанавливается в библиотеку классов через NuGet, в консольный проект добавляется ссылка на EntityFramework.SqlServer.dll.

Строка подключения в обоих проектах выглядит так:

<connectionStrings>
    <add name="DbConnection"
        connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\LanguageCreator.mdf;Initial Catalog=LanguageCreator;Integrated Security=SSPI"
        providerName="System.Data.SqlClient" />
</connectionStrings>

Мой контекстный класс выглядит так:

public class LanguageContext : DbContext {
    public LanguageContext() : base("DbConnection") {
        // Have to set the DataDirectory in code because the wrong one gets set from the config.
        AppDomain.CurrentDomain.SetData("DataDirectory", Directory.GetCurrentDirectory());

        Database.SetInitializer(new CreateDatabaseIfNotExists<LanguageContext>());

        public DbSet<Language> Languages { get; set; }
        public DbSet< ... blablabla various other DbSets following, nothing of interest here.
    }

Вот так выглядит мой шлюз:

public class Gateway {
    public void InitializeDatabase() {
        using (LanguageContext context = new LanguageContext()) {
            context.Database.Initialize(true);

            // I did have a configuration class for migration, which seeds some initial data, which is why I'm trying to read the WordTypes here but I left that thing out this time ... will try to add it later on.
            IEnumerable<WordType> wordTypes = context.WordTypes.AsEnumerable();

            List<Language> languages = context.Languages.ToList();
        }
    }
}

Просто вызов выглядит так:

class Program {
    static void Main(string[] args) {
        Gateway databaseGateway = new Gateway();

        databaseGateway.InitializeDatabase();
    }
}

Теперь, абсолютно ничего особенного, я получаю следующую ошибку при запуске сеанса отладки:

При установлении соединения с SQL Server произошла ошибка, связанная с сетью или конкретным экземпляром. Сервер не найден или не был доступен. Убедитесь, что имя экземпляра указано правильно и что SQL Server настроен на разрешение удаленных подключений. (поставщик: SQL Network Interfaces, ошибка: 50 — Произошла ошибка выполнения локальной базы данных. Невозможно создать автоматический экземпляр. Подробные сведения об ошибке см. в журнале событий приложений Windows.

К сожалению, журнал событий приложений Windows не показывает никаких сведений об этой ошибке. А может я слишком тупой, чтобы найти...

Что на самом деле вызывает эту проблему и как я могу это исправить? Все, что я нашел, касалось доступа к внешним SQL-серверам, но я просто хочу, чтобы EF локально создавал .mdf и подключался к нему.


person Otto Abnormalverbraucher    schedule 27.10.2015    source источник


Ответы (2)


Я очень новичок в Entity Framework и базах данных в целом, но у меня есть пара предложений, которые могут помочь сузить проблему.

  1. «Убедитесь, что имя экземпляра указано правильно и что SQL Server настроен на разрешение удаленных подключений». Посмотрите, не связана ли проблема с сервером, подключившись к нему с помощью другой программы. Если у вас возникли проблемы с подключением к нему за пределами EF, вы можете исключить EF как проблему.

  2. Если можете, оставьте строку подключения или любое упоминание о вашей базе данных SQL и посмотрите, сгенерирует ли EF для вас LocalDB. Я полагаю, что это поведение EF по умолчанию. Если это работает, я думаю, это также предполагает, что есть что-то в вашем SQL-сервере, что доставляет вам неприятности.

Опять же, я очень новичок в этом, поэтому я просто думаю, как бы я попытался решить эту проблему с моими ограниченными знаниями. Надеюсь, это полезно!

person Ethan Fischer    schedule 29.10.2015
comment
Как уже было сказано, у меня нет SQL Server и, следовательно, нет связи с ним. Предполагается, что база данных представляет собой локальный файл .mdf, который еще не существует, но должен быть создан при первом запуске. Это не так, и мне интересно, почему. Я попробую ваше второе предложение сегодня вечером, но я сомневаюсь, что оно сработает. Я передаю имя строки подключения конструктору DbContext, поэтому я предполагаю, что он уведомит, что не может найти строку подключения. Также мне интересно, где будет создан .mdf, поскольку это информация в строке подключения. - person Otto Abnormalverbraucher; 29.10.2015
comment
К сожалению, я получаю то же исключение без строки подключения - person Otto Abnormalverbraucher; 01.11.2015

Хорошо, я понял это случайно. Я установил EntityFramework через NuGet в консольном проекте и вуаля, Visual Studio создала .mdf при запуске сеанса отладки.

Поскольку он все еще работал после удаления EntityFramework, я создал проект заново и проверил наличие различий. Я обнаружил, что записи EntityFramework в app.config все еще присутствуют, поэтому я скопировал их в новый проект, и теперь это тоже сработало.

Поэтому, если вы столкнулись с той же проблемой, попробуйте добавить эти части в app.config вашего консольного проекта (или любого другого типа проекта, который вы используете для доступа к библиотеке классов базы данных):

<configSections>
  <section name="entityFramework" 
           type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
           requirePermission="false" />
</configSections>
<connectionStrings>
  <add name="LanguageCreator.data.LanguageCreatorContext"
       connectionString="Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\MyContext.mdf;Integrated Security=SSPI"
       providerName="System.Data.SqlClient" />
</connectionStrings>
<entityFramework>
  <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
    <parameters>
      <parameter value="mssqllocaldb" />
    </parameters>
  </defaultConnectionFactory>
  <providers>
    <provider invariantName="System.Data.SqlClient"
              type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
  </providers>
</entityFramework>
person Otto Abnormalverbraucher    schedule 08.11.2015