【问题标题】:How to determine the owning table of a column returned by a SQLite query in C#如何确定 C# 中 SQLite 查询返回的列的所属表
【发布时间】:2015-08-26 15:36:15
【问题描述】:

我正在使用System.Data.SQLite。我正在编写一个从任何给定 SQLite 数据库读取数据的 C# 程序。 该程序在给定的数据库上运行许多查询。我查询sqlite_master 表以确定数据库中的表,然后运行PRAGMA 语句来获取每个表的架构。

我的主要问题是;当我执行SELECT * FROM table_1 JOIN table_2 ON table_1.id = table_2.id; 时,我找不到确定每个 id 列来自哪个表的方法。

我希望有人能够指出我能够确定查询结果中每一列来自的表的方向。

我已经能够在NameValueCollection 中获取数据,它不会以我希望的方式处理重复的列名。我本来希望有一个字典,表名作为键,列字典作为值;下面的例子:

{"table_1": {"col_1": value, "col_2": value}, "table_2": {"col_1": value, "col_2": value}}

或者一个合格的列名,这样我就可以访问以下项目:

reader["table_name.column_name"];

我还能够从 DataTable 中的查询中获取数据,它无法以我希望的方式获取数据。上面示例中的 id 列只是简单地附加了一个数字 1 以表示它是重复的。

我用来返回 NameValueCollections 和 DataTable 的两个函数如下:

class DatabaseReader
{
    private string ConnectionString;

    public DatabaseReader(string ConnectionString)
    {
        this.ConnectionString = ConnectionString;
    }

    /// <summary>
    /// Returns a NameValueCollection of the query result
    /// </summary>
    /// <param name="query">The query to be run</param>
    public IEnumerable<NameValueCollection> ExecuteReader(string query)
    {
        SQLiteCommand command = new SQLiteCommand();
        command.CommandText = query;

        using (SQLiteConnection conn = new SQLiteConnection(this.ConnectionString))
        {
            conn.Open();
            // Do things with the open connection
            command.Connection = conn;
            SQLiteDataReader reader;
            using (command)
            {
                reader = command.ExecuteReader();
            }

            if (reader != null)
            {
                while (reader.Read())
                {
                    yield return reader.GetValues();
                }
            }
            else
            {
                throw new Exception(string.Format("{0} query returned nothing"));
            }
        }
    }

    /// <summary>
    /// Returns a DataTable of the query result
    /// </summary>
    /// <param name="query">The query to be run</param>
    public DataTable GetDataTable(string query)
    {
        DataTable dt = new DataTable();
        try
        {
            using (SQLiteConnection cnn = new SQLiteConnection(this.ConnectionString))
            {
                cnn.Open();
                using (SQLiteCommand mycommand = new SQLiteCommand(cnn))
                {
                    mycommand.CommandText = query;
                    using (SQLiteDataReader reader = mycommand.ExecuteReader())
                    {
                        dt.Load(reader);
                        reader.Close();
                    }
                }
                cnn.Close();
            }
        }
        catch (Exception e)
        {
            throw new Exception(e.Message);
        }
        return dt;
    }

}

非常感谢任何帮助! :)

【问题讨论】:

    标签: c# sqlite system.data.sqlite


    【解决方案1】:

    我认为问题出在您的 SQL 查询中。您必须为要从表中检索的每一列设置一个名称。所以你可以使用这个查询:

    SELECT table_1.ID as Tbl1_ID, table_2.ID as Tbl2_ID FROM table_1 JOIN table_2 ON table_1.id = table_2.id;
    

    现在您可以通过名称读取每个列的值,例如:

    reader["Tbl1_ID"];
    

    或者是索引,比如:

    reader[0];
    

    【讨论】:

    • 这是一个很好的解决方法。但是,当我运行此查询时,我不知道表中存在的列(这可以通过编程方式计算出来)并且我总是想要所有列,因此我为什么要执行 SELECT * FROM... 语句。
    • 这就是你不应该使用SELECT *的原因。
    • 是的,如果我回到绘图板并摆脱SELECT *,也许这一切都会更好
    • @MichaelMurphy 当您执行查询时,结果将是简单的表,并且只包含列名和列值。没有关于where was the data retrieve from 的额外数据。所以如果每次查询结果都不一样,我认为你应该改变你的数据库设计,让查询的执行变得简单。
    • 我想我还不清楚。我不知道该工具将使用的数据库,因此使用通用 SQL 语句以及为什么我查询 sqlite_master 表以获取有关数据库中存在的表的信息。我今晚要重新设计一些东西,看看我是否可以删除通用语句。
    猜你喜欢
    • 1970-01-01
    • 2018-07-11
    • 1970-01-01
    • 2022-11-17
    • 1970-01-01
    • 2011-05-31
    • 1970-01-01
    • 1970-01-01
    • 2014-09-27
    相关资源
    最近更新 更多