简体   繁体   中英

Send an Unspecified Number of Parameters to a Method

I have a program that at the moment is hard coded to send a number of parameters that the user inputs into a DBF file. I cannot leave the parameters empty (DBF just doesn't seem to allow it) so now I am simply putting in a blank which is not necessarily a problem.

This is the method so far;

    public bool SendToDBF(string name, string town, string pcode)
    {

        int id, querytype, personID;
        string whatfile, netname, whatProgram, blank;

        id = 1;
        whatfile = "Compns";
        querytype = 1;
        netname = Environment.UserName;
        personID = 8948;
        whatProgram = "Sales";
        blank = "";

        try
        {
            string constr = ConfigurationManager.ConnectionStrings["dbfString"].ConnectionString;
            using (var dbfCon = new OleDbConnection(constr))
            {
                dbfCon.Open();
                var dbfCmd = new OleDbCommand("INSERT INTO fromsql VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", dbfCon);
                dbfCmd.Parameters.Clear();
                dbfCmd.Parameters.AddWithValue("@fq_uniqid", id);
                dbfCmd.Parameters.AddWithValue("@fq_whfile", whatfile);
                dbfCmd.Parameters.AddWithValue("@fq_what", querytype);
                dbfCmd.Parameters.AddWithValue("@fq_whonm", netname);
                dbfCmd.Parameters.AddWithValue("@fq_whoid", personID);
                dbfCmd.Parameters.AddWithValue("@fq_whoprog", whatProgram);
                dbfCmd.Parameters.AddWithValue("@param1", name);
                dbfCmd.Parameters.AddWithValue("@param2", town);
                dbfCmd.Parameters.AddWithValue("@param3", pcode);
                dbfCmd.Parameters.AddWithValue("@param4", blank);
                dbfCmd.Parameters.AddWithValue("@param5", blank);
                dbfCmd.Parameters.AddWithValue("@param6", blank);
                dbfCmd.Parameters.AddWithValue("@param7", blank);
                dbfCmd.Parameters.AddWithValue("@param8", blank);
                dbfCmd.Parameters.AddWithValue("@param9", blank);
                dbfCmd.Parameters.AddWithValue("@param10", blank);
                dbfCmd.Parameters.AddWithValue("@param11", blank);
                dbfCmd.Parameters.AddWithValue("@param12", blank);
                dbfCmd.Parameters.AddWithValue("@param13", blank);
                dbfCmd.Parameters.AddWithValue("@paraml1", blank);
                dbfCmd.Parameters.AddWithValue("@paraml2", blank);

                dbfCmd.ExecuteNonQuery();
                return true;
            }
        }
        catch (OleDbException ex)
        {
            MessageBox.Show("Error Updating MySQL: " + ex);
            return false;
        }
    }

What I would like is that the amount of paramaters sent to DBF is decided on how many fields the user fills in for the company, for example if they fill in just the name, town and post code then SendToDBF will take 3 params as well as the predefined parameters such as ID , Whatfile and QueryType .

Is there a way that I can make SendToDBF take an unspecified number of parameters, and fill in the rest that are not in putted by the user with blanks?

If the type is always string you can use the params keyword in C# :

public static void TestParams(params string[] Params)
{
   foreach (string param in Params) 
    {
        Console.WriteLine(param);
    }
}

And then decide on the value name based on the index in Params

Example:

public static void TestParams(params string[] Params)
{
    // init dbf up here
    int maxParams = 12;
    for(int i = 1; i <= maxParams; i++) 
    {
        string paramName = "@param" + i;
        if(Params.Length >= i)
            dbfCmd.Parameters.AddWithValue(paramName, Params[i - 1]); // array index is zero-based
        else
            dbfCmd.Parameters.AddWithValue(paramName, blank);
    }
}

I don't know the exact context of your problem, but you can:

  1. Convert your parameter list to a dictionary with key / value (a Dictionary, or Dictionary) so you can pass the exact parameters to your method, so you don't get mixed up in the order of each parameter.

So you will have a

new Dictionary<string, string> { {"firstName": "John"}, {"age": "42"} }

and for the rest of the parameters, have an array with keys on which you can diff and populate the remaining with blank (i guess your procedure needs all the parameters)

or another alternative: use a default dictionary containing all parameters with default values for each column:

new Dictionary<string, string> { "status": "1" }

Then you would just merge the defaults with the parameter, then add all the keys and values to the command.

See: Merging dictionaries in C#

  1. If the order is not important for the parameters (which i doubt) you can use the params keyword. See Why use the params keyword? for when to use.

You can use params :

public bool SendToDBF(params  string[] parameters)
{

}

public bool SendToDBF(params  object[] parameters)
{

}

I would build a dictionary of field names and values, and construct the SQL myself. You can pass in the dictionary from the method, or build it internally.

Dictionary<string, object> d = new Dictionary<string, object>();

d["personID"] = 1234;
// ...

The SQL can be built like this:

StringBuilder sb = new StringBuilder();
sb.Append("insert into ");
sb.Append(tableName);
sb.Append(" (");

StringBuilder sbValues = new StringBuilder();
sbValues.Append("values (");

bool first = true;
foreach (KeyValuePair<string, object> kvp in d)
{
    if (first)
    {
        first = false;
    }
    else
    {
        sb.Append(", ");
        sbValues.Append(", ");
    }

    sb.Append(kvp.Key);
    sbValues.Append("?");

    // put the value in a SQL parameter;
    dbfCmd.Parameters.AddWithValue("@" + kvp.Key, kvp.Value);
}

sb.Append(") ");
sbValues.Append(")");

sb.Append(sbValues.ToString());

string fullSql = sb.ToString();

It separates building the values string and the rest of the SQL statement, since you else need to go over the collection twice, which seems unnecessary.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM