C#SQLite参数在不同页面中工作/不工作

时间:2018-09-16 22:44:02

标签: c# sqlite sqlite-net

首次发布。我正在为我的一个小项目尝试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();
    }

在这里,我试图找出问题所在。当我删除参数IdWhere子句时,所有内容都会按照应有的方式进行更新,但是当我尝试使用该参数时,它将永远找不到要更新的行:

    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();
    }

我已经检查过,并且ID存在于数据库中。它应该找到结果。 如果有人知道原因并可以向我解释,那将使我高兴!

更新

我仍然不知道为什么它在第一个示例中起作用,而在另一个示例中却不起作用,但在这里是对我有用的解决方案。

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 :(得分:0)

您可以尝试更改此内容吗?

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 + "%");

现在,您必须在switch / case语句上方声明列表:

 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();
}

更新:

不支持sqllite的GUId。将Guid转换为String或将id的changind数据类型转换为string可能会有所帮助。

查看此处:

SQLite Parameter Issue with Guids