【问题标题】:Datastructure and algorithm [closed]数据结构和算法
【发布时间】:2021-10-17 13:00:52
【问题描述】:

主题: 模拟数据库管理系统的数据结构和算法 要求:

  • 数据存储
  • 查询:支持选择、插入、更新查询

我打算在winform上做,有创建表,选择,删除,更新命令,就像sql一样。但我不知道如何用 C# 编写这些函数。有人有关于 SQL 基本功能的文档吗?请帮我。 任何了解该主题的人都可以逐步指导我吗?我真的不知道该怎么办

【问题讨论】:

    标签: c# winforms data-structures


    【解决方案1】:

    在现代编程中,倾向于将数据(= 模型)与数据的显示方式(= 视图)分开。要将视图连接到模型,我们需要一个适配器类:viewmodel。这三个类一起缩写为 MVVM。考虑阅读有关此的内容。

    将模型和视图分离的好处是,可以将模型重用于其他视图,可以改变模型而不改变视图,或者改变视图而不改变模型。最后,无需表单就可以更轻松地对模型类进行单元测试。

    我提到 MVVM,因为您尝试将数据库处理与 WinForms 混合。数据库处理(模型)与您如何显示获取的数据无关。

    回到你的问题

    显然,显示获取的数据(目前)没有问题。因此,让我们关注如何在 C# 中获取数据库数据。

    有两种主要方法:一种是使用 SQL,通过 DbConnection 和 DbCommand。另一种常用的方法是使用实​​体框架和 LINQ。

    您提到您已经拥有用于获取数据的 SQL。因此,我将专注于该方法。如果您对实体框架感兴趣,请考虑阅读Entity Framework Code First 并在电视上没有任何内容时做一些实验。

    您需要一种方法来创建表。由于表是一起工作的,我的建议是不要创建一个创建一个表的方法,而是创建一个在一次调用中创建数据库的所有表的方法。

    public void CreateAllTables()
    {
        const string sqlText = "Create if not exists TableCustomers (
             Id int,
             FirstName Varchar(30),
             ...
    

    确切的语法在一定程度上取决于您使用的 SQL 方言:MicroSoft? mysql?简单的 SQL?好吧,我想你比我更了解 Sql 文本。关于如何发送这个数据库:

        using (var dbConnection = new DbConnection())
        {
            using (DbCommand dbCommand = dbConnection.CreateCommand())
            {
                dbCommand.CommandText = sqlText;
    

    现在有几种方法可以执行 dbCommand:

    • 检索项目序列:DbCommand.ExecuteReader
    • 只检索一个对象:DbCommand.ExecuteScalar
    • 只执行,不返回数据:DbCommand.ExecuteNonQuery

    在这种情况下:我们只执行命令。在与数据库通信之前,我们必须打开 dbConnection:

                dbConnection.Open();
                dbCommand.ExecuteNonQuery();
            }
        }
    }
    

    DbCommand.ExecuteNonQuery 有一个返回值:受影响的行数。有时检查一下是否发生错误可能会很方便。

    现在来获取一些数据

    public IEnumerable<Product> FetchStudentsByLastName(string lastName)
    {
        const string sqlText = "Select Id, FirstName, LastName, ...
            From tableStudents
            Where LastName = @LastName;"
    

    请注意,我的 SQL 有 @LastName 作为参数!

    开头和CreateTables中的一样:

    using (var dbConnection = new DbConnection())
    {
        using (DbCommand dbCommand = dbConnection.CreateCommand())
        {
            dbCommand.CommandText = sqlText;
    

    填写参数:

            // associate the parameter in the SQL text with the value:
            dbCommand.AddWithValue("@LastName", lastName);
    

    现在我们准备打开 dbConnection 并执行查询。我们希望获取几行,所以我们必须使用DbCommand.ExecuteReader

            dbConnection.Open();
            using (DbDataReader dbReader = dbCommand.ExecuteReader())
            {
    

    dbDataReader 包含获取的数据。使用DbDataReader.Read 找出是否还有要读取的行。如果是这样,请使用GetInt32GetString 等读取每一行中的单元格:

                while (dbReader.Read())
                {
    

    显然有一排。我们选择 Id 作为第 0 列,FirstName 作为第 1 列,LastName 作为第 2 列,等等:

                    Student fetchedStudent = new Student
                    {
                        Id = dbReader.GetInt32(0),          // column 0 is an Int32
                        FirstName = dbReader.GetString(1),  // column 1 is a string
                        LastName = dbReader.GetString(2),
                        ...
                    }
    
                    yield return fetchedStudent;
                }
            }
        }
    }
    

    要添加一个学生,我们做了类似的事情:创建 DbConnection 和 DbCommand。使用 SQL 文本和 AddWithParameter 填充 DbCommand。

    不同的是:我们不希望返回多行,我们只想要添加的学生的Id。

    如何在命令中返回 Id 取决于您使用的 SQL 方言。在 SQLLight 中会是这样的:

    const string sqlText = "INSERT INTO tableStudent (
       FirstName, LastName, ...) Values(@FirstName, @LastName, ...);
       SELECT last_insert_rowid();"
    

    添加新学生后,此 SQL 文本将返回学生的 Id。

    创建 DbConnection 和 DbCommand。那么:

    dbCommand.CommandText = sqlText;
    dbCommand.AddWithValue("@FirstName, firstName);
    dbCommand.AddWithValue("@LastName, lastName);
    ...
    

    打开数据库,执行查询,只有一个结果:ExecuteScalar,返回返回的Id为int:

    dbConnection.Open();
    return (int)dbCommand.ExecuteScalar();
    

    简历

    我已经向您展示了如何使用 DbConnection 和 DbCommand 与数据库进行通信。

    我展示了如何向 SQL 文本添加参数。

    要获取数据行使用ExecuteReader 和逐行读取,使用DbReader.ReadDbReader.GetString(colum number) 等。

    我展示了如何在不返回值的情况下执行:DbCommand.ExecuteNonQuery。用于创建表、删除表、更新表中的行、删除表中的行。

    最后,我展示了如何返回一个值:DbCommand.ExecuteScalar。用于添加新行时返回Id。

    【讨论】: