Вставка данных в таблицу на C#

Я работаю над игрой уже около 2 месяцев и использую базу данных SQL Server для хранения всех данных об игроке. Я пытался записать данные в таблицу Players, но пока безуспешно.

Я попробовал создать метод, в котором я устанавливаю соединение с базой данных и вставляю данные через SqlCommand (SqlClient).

DataManager класс

public static void UpdatePlayerStatistics(string connectionString, string[] playerTextData, int[] playerIntData) 
{
    using (SqlConnection connection = new SqlConnection(connectionString)) 
    {
        SqlCommand cmd = new SqlCommand($"INSERT INTO dbo.Players VALUES ({playerTextData[0]})", connection);
        cmd.CommandType = System.Data.CommandType.Text;

        cmd.Parameters.AddWithValue("@PlayerName", playerTextData[0].ToString());

        connection.Open();
        cmd.ExecuteNonQuery();
        connection.Close();
    }
}

Game класс:

public static string[] playerTextData = new string[4];
/* 
 * 0 - PlayerFirstName
 * 1 - PlayerLastName
 * 2 - PlayerRace
 * 3 - PlayerClass
 */

public static void Main(string[] args)
{
    // Receives player's first name
    Console.WriteLine("Please enter your character's first name: ");
    playerTextData[0] = Console.ReadLine();
    Console.Clear();

    // Receives player's last name
    Console.WriteLine("Please enter your character's last name: ");
    playerTextData[1] = Console.ReadLine();
    Console.Clear();

    // Uploads the basic data to table
    DataManager.UpdatePlayerStatistics(playerTextData, playerIntData);
}

И еще при тестировании вылезла такая ошибка

System.Data.SqlClient.SqlException: неверное имя столбца <First Name>. Неверное имя столбца <Last Name>. Имя столбца или количество предоставленных значений не соответствует определению таблицы.

Не используйте конкатенацию строк для построения команды SQL. В лучшем случае это приведет к таким проблемам, а в худшем — к атакам с использованием SQL-инъекций. Всегда параметризуйте свои утверждения. Вы определили параметр @PlayerName, но никогда его не используете.

gunr2171 21.08.2024 18:29

Вы не определяете, в какие столбцы вы вставляете. Какие столбцы существуют в таблице «Игроки»? Кроме того, вам может быть сложнее использовать массив для хранения имени и фамилии игрока. Возможно, это будет проще понять, если вы используете разные именованные переменные и/или класс. Совершенно произвольно говорить: «В этом массиве индекс 0 является именем, а индекс 1 — фамилией».

gunr2171 21.08.2024 18:34

Пометить это ssms — это все равно, что сообщить нам, что машина, на которой вы ездите, — Sony, потому что эта марка указана на приборной панели магнитолы.

Joel Coehoorn 21.08.2024 18:37

Кроме того, НЕ НУЖНО использовать интерполяцию или конкатенацию строк для включения данных в команду sql. Это одна из тех вещей, которые слишком важны, чтобы делать что-то неправильно, даже для обучения/практики/проверки концептуальной работы.

Joel Coehoorn 21.08.2024 18:38

Наконец, не используйте массивы строк для хранения полей. Определите класс со свойствами для каждого поля. Если вы этого не умеете, значит, вы еще не готовы научиться использовать базы данных.

Joel Coehoorn 21.08.2024 18:40
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
6
69
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Здесь есть чем заняться. Примечания в виде комментариев для пояснения изменений.

// Do NOT use array elements as fields! Classes (or Records) are so much better for this.
public class PlayerData
{
    public string FirstName {get;set;}
    public string LastName {get;set;}
    public string Race {get;set;}
    public string Class {get;set;}
}
// Again: if a class is this simple, with only basic auto-implemented properties, it should probably be a record.
// I left it as a class because someone new to C# may not have seen records yet.
// Also remember, you'll be able to re-use this class when going the other direction and selecting data back out of the database.

public class Program
{
    public static void Main(string[] args)
    {
        // create our player object closer to where it's used
        var player = new PlayerData();

        // Receives player's first name
        Console.WriteLine("Please enter your character's first name: ");
        player.FirstName = Console.ReadLine();
        Console.Clear();

        // Receives player's last name
        Console.WriteLine("Please enter your character's last name: ");
        player.LastName = Console.ReadLine();
        Console.Clear();

        // Uploads the basic data to table
        DataManager.UpdatePlayerStatistics(player);
    }
}

public class DataManager
{
    // private connection string. 
    // Now other types won't be able to connect on their own (no string).
    // This forces data access to go through your data manager, where it belongs.
    // Some apps may opt to have this set via a constructor, load it 
    // from a config file or similar, or use dependency injection
    private static string connectionString = "connection string here";

    // No longer need to pass connection string as an argument
    // Also, we can accept the PlayerData type, with nice named fields
    public static void UpdatePlayerStatistics(PlayerData player) 
    {
        // this could be *const* if we wanted... it will never change!
        // However, I had to guess at the column names.
        // Also note how I included the parameter variables in the string
        string sql = "INSERT INTO dbo.Players (FirstName, LastName) VALUES (@FirstName, @LastName);";
        using var connection = new SqlConnection(connectionString); 
        using var cmd = new SqlCommand(sql, connection);

        // Do NOT use AddWithValue() (it has a serious performance "gotcha" that can crop up)
        // DO use the exact database column type and size from the database
        cmd.Parameters.Add("@FirstName", SqlDbType.NVarChar, 20).Value = player.FirstName;
        cmd.Parameters.Add("@LastName", SqlDbType.NVarChar, 25).Value = player.LastName;

        connection.Open();
        cmd.ExecuteNonQuery();
        // No need to call .Close() because the using directive takes care of it in a better way
    }
}

@HansKeffing Исправлено, хороший улов.

Joel Coehoorn 21.08.2024 21:33

я думаю, что самый простой способ:

                 ExampleEntities1 db = new ExampleEntities1();
                 Tbl(your table name) D = new Tbl(your table name)();
                 D.PlayerFirstName = TxtPlayerFirstName.Text;
                 D.PlayerLastName = TxtPlayerLastName.Text;
                 D.PlayerClass = TxtPlayerClass.Text;
                 D.PlayerRace = Convert.ToInt32(PlayerRace.Text);
                 db.Tbl(your table name).Add(D);
                 db.SaveChanges();
                 this.DialogResult = DialogResult.OK;

таким образом вы легко можете добавить свою дату в winform в базу данных.

Другие вопросы по теме