C # Sqlite Параметр Работает / Не работает на разных страницах - PullRequest
0 голосов
/ 17 сентября 2018

Первое размещение. Я пытаюсь использовать sqlite для своего небольшого проекта, и я столкнулся с чем-то действительно странным. Кажется, проблема в параметре, но я его не понимаю. Может быть, кто-то здесь может объяснить мне, почему это работает в одном месте, но не в другом.

Вот оно: в этом коде все работает отлично:

    public void SaveObject(PlayerCharacter playerCharacter)
    {
        SQLiteConnection sqliteConnection = new SQLiteConnection(ConnectionString.Connection);
        sqliteConnection.Open();

        String query = String.Empty;

        switch (playerCharacter.InternalState)
        {
            case InternalStates.New:
                query = "INSERT INTO PlayerCharacters(Id, Name, ArmorClass, InitiativeBonus) VALUES (@Id, @Name, @ArmorClass, @InitiativeBonus)";
                break;

            case InternalStates.Modified:
                query = @"  UPDATE PlayerCharacters
                            SET Name = @Name,
                                ArmorClass = @ArmorClass,
                                InitiativeBonus = @InitiativeBonus
                            WHERE Id = @Id";
                break;

            case InternalStates.Deleted:
                //To maybe implement in the future
                break;
        }

        List<SQLiteParameter> parameters = new List<SQLiteParameter>()
        {
            new SQLiteParameter("@Id", playerCharacter.Id),
            new SQLiteParameter("@Name", playerCharacter.Name),
            new SQLiteParameter("@ArmorClass", playerCharacter.ArmorClass),
            new SQLiteParameter("@InitiativeBonus", playerCharacter.InitiativeBonus)
        };

        SQLiteCommand command = new SQLiteCommand(query, sqliteConnection);
        command.Parameters.AddRange(parameters.ToArray());

        command.ExecuteNonQuery();

        playerCharacter.SetInternalState(InternalStates.UnModified, true);

        sqliteConnection.Close();
    }

Здесь я попытался выделить проблему. Когда я удаляю параметр Id и предложение Where, все обновляется, как и должно быть, но когда я пытаюсь использовать параметр, он никогда не находит строку для обновления:

    public void SaveObject(Monster monster)
    {
        SQLiteConnection sqliteConnection = new SQLiteConnection(ConnectionString.Connection);
        sqliteConnection.Open();

        String query = String.Empty;

        switch (monster.InternalState)
        {
            case InternalStates.New:
                query = @"  INSERT INTO Monsters(Id,
                                                Name,
                                                Size,
                                                Type,
                                                Subtype,
                                                Alignment,
                                                ArmorClass,
                                                HitPoints,
                                                HitDice,
                                                Speed,
                                                DamageVulnerabilities,
                                                DamageResistances,
                                                DamageImmunities,
                                                ConditionImmunities,
                                                Senses,
                                                Languages,
                                                ChallengeRating) 
                            VALUES (@Id,
                                    @Name,
                                    @Size,
                                    @Type,
                                    @Subtype,
                                    @Alignment,       
                                    @ArmorClass,
                                    @HitPoints,
                                    @HitDice,
                                    @Speed,
                                    @DamageVulnerabilities,
                                    @DamageResistances,
                                    @DamageImmunities,
                                    @ConditionImmunities,
                                    @Senses,
                                    @Languages,
                                    @ChallengeRating)";
                break;

            case InternalStates.Modified:
                query = @"  UPDATE Monsters
                            SET Name = @Name
                            WHERE Monsters.Id = @Id";

                //Size = @Size,
                //                Type = @Type,
                //                Subtype = @Subtype,
                //                Alignment = @Alignment,
                //                ArmorClass = @ArmorClass,
                //                HitPoints = @HitPoints,
                //                HitDice = @HitDice,
                //                Speed = @Speed,
                //                DamageVulnerabilities = @DamageVulnerabilities,
                //                DamageResistances = @DamageResistances,
                //                DamageImmunities = @DamageImmunities,
                //                ConditionImmunities = @ConditionImmunities,
                //                Senses = @Senses,
                //                Languages = @Languages,
                //                ChallengeRating = @ChallengeRating
                break;

            case InternalStates.Deleted:
                //To maybe implement in the future
                break;
        }

        List<SQLiteParameter> parameters = new List<SQLiteParameter>()
        {
            new SQLiteParameter("@Id", monster.Id ),
            new SQLiteParameter("@Name", monster.Name)
            //new SQLiteParameter("@Size", monster.Size),
            //new SQLiteParameter("@Type", monster.Type),
            //new SQLiteParameter("@Subtype", monster.Subtype),
            //new SQLiteParameter("@Alignment", monster.Alignment),
            //new SQLiteParameter("@ArmorClass", monster.ArmorClass),
            //new SQLiteParameter("@HitPoints", monster.HitPoints),
            //new SQLiteParameter("@HitDice", monster.HitDice),
            //new SQLiteParameter("@Speed", monster.Speed),
            //new SQLiteParameter("@DamageVulnerabilities", monster.DamageVulnerabilities),
            //new SQLiteParameter("@DamageResistances", monster.DamageResistances),
            //new SQLiteParameter("@DamageImmunities", monster.DamageImmunities),
            //new SQLiteParameter("@ConditionImmunities", monster.ConditionImmunities),
            //new SQLiteParameter("@Senses", monster.Senses),
            //new SQLiteParameter("@Languages", monster.Languages),
            //new SQLiteParameter("@ChallengeRating", monster.ChallengeRating)
        };

        SQLiteCommand command = new SQLiteCommand(query, sqliteConnection);
        command.Parameters.AddRange(parameters.ToArray());

        int i = command.ExecuteNonQuery();

        monster.SetInternalState(InternalStates.UnModified, true);

        sqliteConnection.Close();
    }

Я уже проверил, и идентификатор существует в базе данных. Это должно найти результат. Если кто-то знает почему и может мне это объяснить, это сделает мой день!

UPDATE

Я до сих пор не знаю, почему это работает в первом примере, а не во втором, но вот решение, которое работает для меня.

Параметр sql имеет свойство DbType, и оно автоматически устанавливается в соответствии со значением, в моем случае это значение Guid. В Sqlite типа uniqueidentifier не существует, и он обрабатывается как строка. Итак, вот что я сделал:

        ...

        List<SQLiteParameter> parameters = new List<SQLiteParameter>()
        {
            new SQLiteParameter("@Id", monster.Id ) {DbType = DbType.String},
            new SQLiteParameter("@Name", monster.Name)
            //new SQLiteParameter("@Size", monster.Size),
            //new SQLiteParameter("@Type", monster.Type),
            //new SQLiteParameter("@Subtype", monster.Subtype),
            //new SQLiteParameter("@Alignment", monster.Alignment),
            //new SQLiteParameter("@ArmorClass", monster.ArmorClass),
            //new SQLiteParameter("@HitPoints", monster.HitPoints),
            //new SQLiteParameter("@HitDice", monster.HitDice),
            //new SQLiteParameter("@Speed", monster.Speed),
            //new SQLiteParameter("@DamageVulnerabilities", monster.DamageVulnerabilities),
            //new SQLiteParameter("@DamageResistances", monster.DamageResistances),
            //new SQLiteParameter("@DamageImmunities", monster.DamageImmunities),
            //new SQLiteParameter("@ConditionImmunities", monster.ConditionImmunities),
            //new SQLiteParameter("@Senses", monster.Senses),
            //new SQLiteParameter("@Languages", monster.Languages),
            //new SQLiteParameter("@ChallengeRating", monster.ChallengeRating)
        };

        ...

1 Ответ

0 голосов
/ 17 сентября 2018

Можете ли вы попробовать изменить это:

UPDATE Monsters
SET Name = @Name
WHERE Monsters.Id = @Id

На

UPDATE Monsters SET Name = @Name
WHERE Monsters.Id like @Id

И в C #:

    new SQLiteParameter("@Id", "%" + monster.Id + "%");

Теперь вы должны объявить список вышеПереключатель / регистр:

 List<SQLiteParameter> parameters = new List<SQLiteParameter>()
        {
            // remove the @id parameter here
            new SQLiteParameter("@Name", monster.Name)
            //new SQLiteParameter("@Size", monster.Size),
            //new SQLiteParameter("@Type", monster.Type),
            //new SQLiteParameter("@Subtype", monster.Subtype),
            //new SQLiteParameter("@Alignment", monster.Alignment),
            //new SQLiteParameter("@ArmorClass", monster.ArmorClass),
            //new SQLiteParameter("@HitPoints", monster.HitPoints),
            //new SQLiteParameter("@HitDice", monster.HitDice),
            //new SQLiteParameter("@Speed", monster.Speed),
            //new SQLiteParameter("@DamageVulnerabilities", monster.DamageVulnerabilities),
            //new SQLiteParameter("@DamageResistances", monster.DamageResistances),
            //new SQLiteParameter("@DamageImmunities", monster.DamageImmunities),
            //new SQLiteParameter("@ConditionImmunities", monster.ConditionImmunities),
            //new SQLiteParameter("@Senses", monster.Senses),
            //new SQLiteParameter("@Languages", monster.Languages),
            //new SQLiteParameter("@ChallengeRating", monster.ChallengeRating)
        };

В вашем случае для вставки:

parameters.Add(new SQLiteParameter("@Id", monster.Id ));

В вашем случае для обновления:

parameters.Add(new SQLiteParameter("@Id", "%" + monster.Id + "%"));

Ваш окончательный код:

public void SaveObject(Monster monster)
{
    SQLiteConnection sqliteConnection = new SQLiteConnection(ConnectionString.Connection);
    sqliteConnection.Open();

    String query = String.Empty;
    List<SQLiteParameter> parameters = new List<SQLiteParameter>()
    {
        new SQLiteParameter("@Name", monster.Name)
        //new SQLiteParameter("@Size", monster.Size),
        //new SQLiteParameter("@Type", monster.Type),
        //new SQLiteParameter("@Subtype", monster.Subtype),
        //new SQLiteParameter("@Alignment", monster.Alignment),
        //new SQLiteParameter("@ArmorClass", monster.ArmorClass),
        //new SQLiteParameter("@HitPoints", monster.HitPoints),
        //new SQLiteParameter("@HitDice", monster.HitDice),
        //new SQLiteParameter("@Speed", monster.Speed),
        //new SQLiteParameter("@DamageVulnerabilities", monster.DamageVulnerabilities),
        //new SQLiteParameter("@DamageResistances", monster.DamageResistances),
        //new SQLiteParameter("@DamageImmunities", monster.DamageImmunities),
        //new SQLiteParameter("@ConditionImmunities", monster.ConditionImmunities),
        //new SQLiteParameter("@Senses", monster.Senses),
        //new SQLiteParameter("@Languages", monster.Languages),
        //new SQLiteParameter("@ChallengeRating", monster.ChallengeRating)
    };

    switch (monster.InternalState)
    {
        case InternalStates.New:
            query = @"  INSERT INTO Monsters(Id,
                                            Name,
                                            Size,
                                            Type,
                                            Subtype,
                                            Alignment,
                                            ArmorClass,
                                            HitPoints,
                                            HitDice,
                                            Speed,
                                            DamageVulnerabilities,
                                            DamageResistances,
                                            DamageImmunities,
                                            ConditionImmunities,
                                            Senses,
                                            Languages,
                                            ChallengeRating) 
                        VALUES (@Id,
                                @Name,
                                @Size,
                                @Type,
                                @Subtype,
                                @Alignment,       
                                @ArmorClass,
                                @HitPoints,
                                @HitDice,
                                @Speed,
                                @DamageVulnerabilities,
                                @DamageResistances,
                                @DamageImmunities,
                                @ConditionImmunities,
                                @Senses,
                                @Languages,
                                @ChallengeRating)";
                parameters.Add(new SQLiteParameter("@Id", monster.Id ));
            break;

        case InternalStates.Modified:
            query = @"  UPDATE Monsters
                        SET Name = @Name
                        WHERE Monsters.Id like @Id";

            //Size = @Size,
            //                Type = @Type,
            //                Subtype = @Subtype,
            //                Alignment = @Alignment,
            //                ArmorClass = @ArmorClass,
            //                HitPoints = @HitPoints,
            //                HitDice = @HitDice,
            //                Speed = @Speed,
            //                DamageVulnerabilities = @DamageVulnerabilities,
            //                DamageResistances = @DamageResistances,
            //                DamageImmunities = @DamageImmunities,
            //                ConditionImmunities = @ConditionImmunities,
            //                Senses = @Senses,
            //                Languages = @Languages,
            //                ChallengeRating = @ChallengeRating
            parameters.Add(new SQLiteParameter("@Id", "%" + monster.Id + "%"));
            break;

        case InternalStates.Deleted:
            //To maybe implement in the future
            break;
    }

    SQLiteCommand command = new SQLiteCommand(query, sqliteConnection);
    command.Parameters.AddRange(parameters.ToArray());

    int i = command.ExecuteNonQuery();

    monster.SetInternalState(InternalStates.UnModified, true);

    sqliteConnection.Close();
}

Обновление:

Нет поддержки GUId для sqllite.Преобразование Guid в String или изменение идентификатора id в строку может вам помочь.

См. Здесь:

Ошибка параметра SQLite с направляющими

...