SqlCommand 不从 C# 应用程序(MS Access 数据库)返回结果

问题描述 投票:0回答:1

我正在尝试从 C# Web 表单连接到 MS Access 数据库。

我这样做了:

var parameters = new KeyValuePair<string, object>[]
             {
                new KeyValuePair<string, object>("@ProjectId", currentInfo.ProjectId),
                new KeyValuePair<string, object>("@core", Convert.ToInt16(catalogue.Core.ToString())),
                new KeyValuePair<string, object>("@sizee", catalogue.Size)),
                new KeyValuePair<string, object>("@applicationId", Convert.ToInt32(applicationComboBox.SelectedValue.ToString()))
             };
DataTable typesTable = helper.GetRowsByQuery("FillType",parameters, currentInfo.DBPath);

这是连接数据库的方法:

public DataTable GetRowsByQuery(string queryOrTable, KeyValuePair<string, object>[] parameters, string dbPath)
{
    DataTable table = new DataTable();

    OleDbDataAdapter adapter = new OleDbDataAdapter();
    OleDbConnection connection = new OleDbConnection(GetStringConnection(dbPath));

    string sqlCommand = GetSqlCommand(queryOrTable);

    OleDbCommand command = new OleDbCommand(sqlCommand, connection);

    if (parameters != null)
    {
        foreach (KeyValuePair<string, object> o in parameters)
        {
            var parameter = new OleDbParameter(o.Key, o.Value);
            SetOleDbTypeAndSize(parameter, o.Value);
            command.Parameters.Add(parameter);                
        }
    }

    command.CommandText = sqlCommand;

    adapter.SelectCommand = command;

    try
    {
        connection.Open();

        if (table == null)
        {
            table = new DataTable();
            table.Locale = System.Globalization.CultureInfo.InvariantCulture;
            adapter.FillSchema(table, SchemaType.Source);
        }

        adapter.Fill(table);
    }
    finally
    {
        if (connection.State == ConnectionState.Open)
        {
            connection.Close();
        }
    }

    return table;
}

查询命令是这样的

SELECT DISTINCT Catalogue.Type  
FROM (CableProperty  
INNER JOIN Catalogue ON CableProperty.CatalogueId = Catalogue.Id)    
WHERE (Catalogue.Core = @core) 
  AND (Catalogue.[Size] = '@sizee') 
  AND (CableProperty.ProjectId = @projectId) 
  AND (CableProperty.CableApplicationId = @applicationId) 
               

查询直接返回 MS Access 数据库本身的结果,但在我的 C# 应用程序中不返回任何结果....

如果我删除

Catalogue
上的内连接条件:

(Catalogue.Core = @core) AND (Catalogue.[Size] = '@sizee')

它也会在应用程序中返回结果。

c# visual-studio ms-access
1个回答
0
投票

如评论中所述,不要用引号将参数引起来。

而且,真的不需要尝试创建自己的参数列表(密钥对),因为 ADO.NET SQL 命令对象已经为您提供了这样一个预先构建的集合。

请记住,使用 MS-Access 数据引擎时,参数的顺序很重要,并且必须与它们在查询中出现的顺序匹配。

所以,这个:

        string sSQL =
            @"SELECT DISTINCT Catalogue.Type  
            FROM (CableProperty  
            INNER JOIN Catalogue ON CableProperty.CatalogueId = Catalogue.Id)    
            WHERE (Catalogue.Core = @core) 
              AND (Catalogue.[Size] = @sizee) 
              AND (CableProperty.ProjectId = @projectId) 
              AND (CableProperty.CableApplicationId = @applicationId)";


        OleDbCommand cmdSQL = new OleDbCommand(sSQL);
        cmdSQL.Parameters.Add("@core", OleDbType.Integer).Value = 123;
        cmdSQL.Parameters.Add("@sizee", OleDbType.VarWChar).Value = "big";
        cmdSQL.Parameters.Add("@projectId", OleDbType.Integer).Value = 789;
        cmdSQL.Parameters.Add("@applicationId", OleDbType.Integer).Value = 5555;

        DataTable CatItems = General.MyRstP(cmdSQL);

那么,想要一个可以在整个应用程序中使用的易于使用的“通用”例程吗?

我建议这个公共静态例程:

    public static DataTable MyRstP(OleDbCommand cmd)
    {
        DataTable rstData = new DataTable();
        using (OleDbConnection conn = new OleDbConnection(GetConStr()))
        {
            using (cmd)
            {
                cmd.Connection = conn;
                try
                {
                    conn.Open();
                    rstData.Load(cmd.ExecuteReader());
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Error: " + ex.Message);
                }
            }
        }
        return rstData;
    }       

请注意,您甚至可以使用“?”对于 SQL 中的参数,因为正如我所指出的,在 Access 的情况下,参数名称实际上并不重要,重要的是参数添加的顺序。

因此,我认为尝试创建自己的密钥对没有什么价值,因为如上所述,ADO.NET SQL 命令对象已经具有这样的内置集合,更重要的是,您可以使用 OleDbType 强强制转换(自动)输入适合您的参数类型。

另请注意例程如何将连接对象包装在 using 语句中,强烈建议这样做以正确处理与数据库的连接。

© www.soinside.com 2019 - 2024. All rights reserved.