Почему моя таблица не создается?

У меня есть этот код в моем приложении Winforms для создания таблицы в существующей базе данных (которую я создал, следуя тому, что написано здесь):

private void CreateTables()
{
    string connStr = @"Data Source=
      (LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|
      \AYttFM.mdf;Integrated Security=True";
    using (var connection = new 
System.Data.SqlClient.SqlConnection(connStr))
    {
        try
        {
            connection.Open();
            using (var command = connection.CreateCommand())
            {
                StringBuilder sb = new StringBuilder();
                sb.Append("CREATE TABLE [dbo].[AssignmentHistory] ");
                sb.Append("(");
                sb.Append("[Id] INT NOT NULL PRIMARY KEY, ");
                sb.Append("[WeekOfAssignment] DATE NOT NULL,");
                sb.Append("[TalkType] INT NOT NULL,");
                sb.Append("[StudentID_FK] INT NOT NULL, ");
                sb.Append("[AssistantID_FK] INT NOT NULL, ");
                sb.Append("[CounselPoint] INT NOT NULL");
                sb.Append(")");

                command.CommandText = sb.ToString();
                command.ExecuteNonQuery();
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }
}

Работает без нареканий, но таблица не создается. При обновлении папки "Подключение данных" и ее папки "Таблицы" в обозревателе серверов в Visual Studio Community 2015 таблицы не отображаются.

Я что-то упустил в коде выше?

Примечание. Я разбил connStr на несколько строк выше для целей форматирования; в реальном коде connStr находится в одной строке.

Я также не могу подключиться к файлу .mdf через LINQPad, используя «LINQ to SQL по умолчанию» и поставщика SQL Server и переходя к файлу .mdf в моем проекте (C:\AYttFMApp\AYttFMScheduler\AYttFMScheduler\AYttFM. мдф). Он говорит мне, что есть ошибка сети:

введите здесь описание изображения

Я получаю это независимо от того, использую ли я сервер по умолчанию ".\SQLEXPRESS" или устанавливаю его на имя моей машины (это единственная запись в разделе "Серверы" в обозревателе серверов Visual Studio).

ОБНОВИТЬ

Я перезагрузил свой ноутбук, но это не помогло. Соединения данных Server Explorer ничего не показывают, даже после того, как я обновляюсь и пытаюсь добавить его, с именем моей машины в качестве имени сервера (в конце концов, это то, что он говорит, что сервер есть в Server Explorer), и выбор файла .mdf дает у меня та же ошибка при тестировании соединения, что и у LINQPad.

ОБНОВЛЕНИЕ 2

Все любопытнее и любопытнее: теперь, когда я запускаю свое приложение, когда оно доходит до кода создания таблицы, я получаю сообщение об исключении, в котором говорится, что таблица AssignmentHistory уже создана. Тем не менее, если я посмотрю в Server Explorer, хотя сама база данных снова вернулась, ее папка Tables по-прежнему пуста. Как стол может одновременно быть и не быть?

Мне все еще интересно, неверны ли свойства, установленные в файле .mdf; как я написал в комментарии ниже, все свойства имеют значения по умолчанию: «Копировать в выходной каталог» установлено значение «Копировать всегда», а для «Действие сборки» установлено значение «Содержимое». Следует ли изменить одно из них?


person B. Clay Shannon    schedule 09.02.2016    source источник
comment
можете ли вы опубликовать значение command.Connection.ConnectionString непосредственно перед строкой executeNonQuery?   -  person muratgu    schedule 09.02.2016
comment
Это: Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\AYttFM.mdf;Integrated Security=True   -  person B. Clay Shannon    schedule 09.02.2016
comment
у вас, вероятно, есть два файла базы данных. попробуйте абсолютный путь к файлу.   -  person muratgu    schedule 09.02.2016
comment
Спасибо, но я решил сериализовать/десериализовать общие списки пользовательских классов в json и использовать LINQ to Objects для запроса общих списков.   -  person B. Clay Shannon    schedule 09.02.2016


Ответы (2)


Если код не выдает никаких исключений в строке command.ExecuteNonQuery(), значит, запрос завершился и таблица должна быть там. Возможно, вы просто просматриваете не ту базу данных, так как используете файл LocalDb. Если проект включает .MDF в виде файла, и он помечен как всегда копируемый в целевой каталог, то происходит то, что VS всегда просматривает неизмененную копию, а оператор Execute всегда завершается во время отладки, потому что неизмененная копия всегда заменяя копию, которая используется во время выполнения.

DataDirectory указывает заполнитель для местоположения, которое обычно назначается при запуске приложения. Вы можете получить полный путь к используемому файлу .mdf следующим образом:

var fullFilePath = System.IO.Path.Combine(AppDomain.CurrentDomain.GetData("DataDirectory").ToString(), "AYttFM.mdf");

Я добавил имя вашей .mdf LocalDb в конец пути.

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

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


Изменить на основе ваших последних правок

«Ссылка на объект не указывает на экземпляр объекта» - это то, что я получаю после запуска предоставленной вами строки.

Я предположил, что вы устанавливали местоположение DataDirectory вручную, приношу свои извинения. Если вы не устанавливаете переменную вручную, то для приложения Windows расположением по умолчанию является путь .exe. Таким образом, код должен быть обновлен до следующего:

var fullFilePath = System.IO.Path.Combine(System.Reflection.Assembly.GetExecutingAssembly().Location.ToString(), "AYttFM.mdf");

Это вероятно разрешится чем-то вроде .\yourProjectFolder\debug\bin\AYttFM.mdf.

Все свойства имеют значения по умолчанию: «Копировать в выходной каталог» установлено значение «Копировать всегда», а для «Действие сборки» установлено значение «Содержимое».

Так что это подтверждает то, что я написал ранее. Каждый раз, когда вы выполняете сборку, он копирует .mdf в ваш исполняемый каталог и в основном обновляет базу данных до исходного состояния. Обратите внимание, что вы можете выполнять несколько запусков из Visual Studio, что означает, что если все уже было скомпилировано и ничего не изменилось, новый .exe и контент не будут повторно скопированы поверх существующего. Вот почему вы иногда видите исключение, а иногда нет, это просто зависит от того, был ли перезаписан .mdf или нет.

Следует ли изменить что-либо из этого?

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

Из MSDN — Свойства файла

Копировать в выходной каталог

Это свойство определяет условия, при которых выбранный исходный файл будет скопирован в выходной каталог. Выберите Не копировать, если файл никогда не будет копироваться в выходной каталог. Выберите Всегда копировать, если файл всегда нужно копировать в выходной каталог. Выберите Копировать, если новее, если файл должен быть скопирован только в том случае, если он новее, чем существующий файл с таким же именем в выходном каталоге.

Если вы хотите открыть файл .mdf, все, что вам нужно сделать, это дважды щелкнуть по нему в проекте VS, он должен открыться в Server Explorer -> Data Connections. Нет причин открывать выходной файл (копия .mdf) в вашем дизайнере, я бы только отредактировал файл в вашем проекте, так как с вашими текущими настройками это главный файл, который будет перезаписан. выходной файл каждый раз.

У меня нет опыта работы с LINQPad, поэтому я не могу сказать, может ли это приложение подключаться к экземпляру LocalDb или нет. Вот сообщение о том, как это сделать из предыдущий вопрос SO.

person Igor    schedule 09.02.2016
comment
Ссылка на объект, не установленная на экземпляр объекта, - это то, что я получаю после запуска предоставленной вами строки. - person B. Clay Shannon; 09.02.2016
comment
Все свойства имеют значения по умолчанию: для параметра «Копировать в выходной каталог» установлено значение «Всегда копировать», а для параметра «Действие сборки» установлено значение «Содержимое». Следует ли изменить одно из этих значений? - person B. Clay Shannon; 09.02.2016
comment
Таким образом, файл .mdf находится в \bin\debug, но даже после установки пути к нему в DataConnections в Server Explorer - хотя проверка соединения прошла успешно - он не показывает таблицу. Вместо этого я решил использовать json [de]сериализацию и LINQ to Objects. Спасибо за вашу помощь, но, как сказал Чак Берри, я не могу в это ввязываться. - person B. Clay Shannon; 09.02.2016

Откройте диспетчер конфигурации SQL Server и проверьте, работает ли ваш сервер. Если нет - запустите:введите здесь описание изображения

person Verbon    schedule 09.02.2016
comment
Кажется, у меня это не установлено; мне действительно это нужно только для локальных баз данных? Кажется, это должно быть намного проще; Я могу изучить SQLite... - person B. Clay Shannon; 09.02.2016