0

我尝试用谷歌搜索找到解决方案,但我得到的只是完全不相关的结果或涉及二维数组的结果,就像这里的一个:http: //social.msdn.microsoft.com/Forums/vstudio/en-US/bb4d54d3 -14d7-49e9-b721-db4501db62c8/how-does-one-increment-a-value-in-a-two-dimensional-array,这不适用。

说我有这个声明:

var db = Database.Open("Content");
var searchTerms = searchText.Split('"').Select((element, index) => index % 2 == 0 ? element.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries) : new string[] { element }).SelectMany(element => element).ToList();
int termCount = searchTerms.Count;

注意: 您真正需要知道的searchTerms是,它保存了用户在搜索栏中键入的许多搜索词。LINQ 表达式所做的所有事情就是确保将 qoutes 中包含的文本视为单个搜索词。为了这个问题的目的,实际上没有必要知道所有这些。

然后我编译了(使用 for 循环来循环searchTerms列表中的每个项目)一个用作SELECTSQL 查询的字符串。

这是一个示例,它显示了使用@0, @1, etc.占位符编译此字符串的一部分,以便我的查询被参数化。

searchQueryString = "SELECT NULL AS ObjectID, page AS location, 'pageSettings' AS type, page AS value, 'pageName' AS contentType, ";

for (int i=0; i<termCount; i++)
{
    if(i != 0)
    {
        searchQueryString += "+ ";
    }

    searchQueryString += "((len(page) - len(replace(UPPER(page), UPPER(@" + i + "), ''))) / len(@" + i + ")) ";
}

searchQueryString += "AS occurences ";

注意: 关于上述代码,您真正需要了解的只是我将 的递增值连接 i @ 符号以动态编译占位符值。

以上所有方法都可以正常工作,但后来,我必须使用一些类似的东西(只是我不知道在运行之前我需要多少参数):

foreach (var row in db.Query(searchQueryString, searchTerms[0]))
{
    @row.occurences
}

为了澄清: 我需要一些额外的参数(即除了参数之外 searchQueryString )等于 searchTerms 列表中的项目数并且它们必须引用正确的索引(有效地引用从最低到最高的每个索引,按顺序,当然用逗号分隔。

此外,我当然需要使用递增值来引用列表的适当索引,如果我什至可以做到那么远,我也不知道该怎么做。我可以i++以某种方式使用吗?

我知道 C# 很强大,但也许我要求太多了?

4

3 回答 3

1

对可变数量的参数使用 params 关键字。使用 params,传递给 any 函数的参数由编译器更改为临时数组中的元素。

static int AddParameters(params int[] values)
{
    int total = 0;
    foreach (int value in values)
    {
      total += value;
    }
    return total;
}

并且可以称为

int add1 = AddParameters(1);
int add2 = AddParameters(1, 2);
int add3 = AddParameters(1, 2, 3);
int add4 = AddParameters(1, 2, 3, 4);

//-----------根据下面的评论编辑回复---您可以使用这样的东西来与 SQL 一起使用

void MYSQLInteractionFunction(String myConnectionString)
 {
    String searchQueryString = "SELECT NULL AS ObjectID, page AS location, 'pageSettings' AS type, page AS value, 'pageName' AS contentType, ";
    SqlConnection myConnection = new SqlConnection(myConnectionString);
    SqlCommand myCommand = new SqlCommand(searchQueryString, myConnection);
    myConnection.Open();

    SqlDataReader queryCommandReader = myCommand.ExecuteReader();
    // Create a DataTable object to hold all the data returned by the query.
    DataTable dataTable = new DataTable();

    // Use the DataTable.Load(SqlDataReader) function to put the results of the query into a DataTable.
    dataTable.Load(queryCommandReader);

    Int32 rowID = 0; // or iterate on your Rows - depending on what you want
    foreach (DataColumn column in dataTable.Columns)
    {
       myStringList.Add(dataTable.Rows[rowID][column.ColumnName] + " | ");
       rowID++;
     }
     myConnection.Close();

     String[] myStringArray = myStringList.ToArray();
     UnlimitedParameters(myStringArray);
}

static void UnlimitedParameters(params string[] values)
{
    foreach (string strValue in values)
    {
        // Do whatever you want to do with this strValue
     }
 }
于 2013-07-09T16:15:15.693 回答
0

我不确定我是否完全理解您对问题的需求,但看起来您正在用另一个值替换 SQL 中的一系列占位符。如果是这种情况,您可以使用 String.Format 替换如下值:

        object val = "a";
        object anotherVal = 2.0;
        var result = string.Format("{0} - {1}", new[] { val, anotherVal });

这样,您可以通过简单地将参数数组创建为正确的大小来替换任意数量的值。

如果您正在动态创建 SQL 查询,那么您需要警惕 SQL 注入,并且从这个角度来看,将用户提供的文本直接替换到查询中是有点禁忌的。避免这种情况的最佳方法是在查询中使用参数,然后自动对其进行清理以防止 SQL 注入。不过,您仍然可以使用“参数数组”参数来实现您所需要的,例如:

    public IDataReader ExecuteQuery(string sqlQuery, params string[] searchTerms)
    {
        var cmd = new SqlCommand { CommandText = sqlQuery };

        for (int i = 0; i < searchTerms.Length; i++)
        {
           cmd.Parameters.AddWithValue(i.ToString(), searchTerms[i]);
        }

        return cmd.ExecuteReader();
    }

显然,如果需要,您还可以根据 searchTerms 数组的长度在此方法中构建 sql 字符串

于 2013-07-09T16:06:39.493 回答
0

好吧,对于这个问题可能看起来多么复杂,答案最终变得非常简单。我想这很容易被忽视,因为我以前从未这样做过,其他人可能认为这太明显了,不是我想要的。但是,我以前从未尝试过传递可变长度的参数,甚至不知道它是否可能(好吧,我想我知道它是可能的,但可能与我的方法相距甚远。知道)。

无论如何,我尝试过:

foreach (var row in db.Query(searchQueryString, searchTerms)) //searchTerms is a list of strings.
{
    //Do something for each row returned from the sql query.
}

假设如果它可以处理可变长度数量的参数(请记住,在Database.Query()方法中第一个参数之后传递的每个参数都被视为查询字符串中占位符的填充符(例如,@0, @1, @2, etc.),它可以从列表中接受它,如果它可以来自大批。

这个假设我真的不能再错了,因为传递一个列表会引发错误。然而,当我最终崩溃,将列表转换为数组并尝试传递数组而不是列表时,我感到很惊讶。

的确,这是对我最初的问题的简短回答,如果我只是给它一个数组,它就很容易工作(有点太容易了,我想这就是为什么我如此确定它不会工作的原因):

string[] searchTermsArray = searchTerms.ToArray();

foreach (var row in db.Query(searchQueryString, searchTermsArray)) //searchTermsArray is an array of strings.
{
    //Do something for each row returned from the sql query.
}

上面的代码片段确实是成功回答我原来的问题所需要的。

于 2013-07-10T13:40:37.330 回答