C# 使用 LINQ Query 将记录与进程数组的结果进行比较

Posted

技术标签:

【中文标题】C# 使用 LINQ Query 将记录与进程数组的结果进行比较【英文标题】:C# Using LINQ Query compare the records with result of process array 【发布时间】:2015-07-29 11:48:19 【问题描述】:

我编写了以下代码来比较 DataSet 的记录(即)一列的记录。我得到以下异常:

ex:" 索引超出了数组的范围。"

  public void GetRunningTask()
  
      // Process[] lstprocess = Process.GetProcesses();
      conn=new SqlConnection("Data Source=.; Initial Catalog='TTES'; Integrated Security=SSPI;");
      da=new SqlDataAdapter("Select AppName from LRNSetting", conn);
      ds=new DataSet();
      da.Fill(ds,"LRNSetting");

      // Process[] lstprocess = Process.GetProcesses();
      for (int k = 0; k < ds.Tables[0].Rows.Count; k++)
      
        Process[] lstprocess = Process.GetProcesses();
        // DataRow dr=ds.Tables[0].Rows.Cast<DataRow>().Single(row=>row["AppName"])

        var pro = from p in lstprocess
                 //where p.ProcessName.Contains("LRCDual")
                 //where p.ProcessName.Contains(ds.Tables[0].Rows[k].ItemArray)  //added temporary
                 where (p.ProcessName.Contains(ds.Tables[0].Rows[0].ItemArray[k].ToString()))
                 select p;
       
  

【问题讨论】:

【参考方案1】:

虽然您在 ds.Tables[0].Rows.Count 上进行了迭代,但您使用的是 ItemArray 的计数器,而不是预期的 Rows

ds.Tables[0].Rows[0].ItemArray[k].ToString()

我建议你检查一下你的逻辑

【讨论】:

where (p.ProcessName.Contains(ds.Tables[0].Rows[0].ItemArray[k].ToString())) //这里我想比较一下进程名取自GetProcess 与数据库记录,其中包含 exe 名称的数据集记录(即我手动输入的进程名称)。 所以,我想选择那些也应该出现在我的数据库记录中的进程。 例如。 ConsoleApplication1.exe , ConsoleApplication2.exe 这些进程正在系统中运行,我只有“ConsoleApplication1”的记录,那么它应该只选择这条记录。 为 ItemArray 创建另一个循环,因此您的代码将类似于 'where (p.ProcessName.Contains(ds.Tables[0].Rows[k].ItemArray[m].ToString() )) ' 其中 'm' 是一个新的迭代变量,它为 Row[k] 中的所有 itemArrays 循环【参考方案2】:

您需要检查您的代码。 您在表的 Rows Count 上进行了迭代,但您使用的是 ItemArray 的计数器,而不是预期的 Rows, 替换

var pro = from p in lstprocess
             //where p.ProcessName.Contains("LRCDual")
             //where p.ProcessName.Contains(ds.Tables[0].Rows[k].ItemArray)  //added temporary
             where (p.ProcessName.Contains(ds.Tables[0].Rows[0].ItemArray[k].ToString()))
             select p; 

这段代码用

var pro = from p in lstprocess
             //where p.ProcessName.Contains("LRCDual")
             //where p.ProcessName.Contains(ds.Tables[0].Rows[k].ItemArray)  //added temporary
             where (p.ProcessName.Contains(ds.Tables[0].Rows[k].ItemArray['CollumnName'].ToString()))
             select p;

【讨论】:

【参考方案3】:

您的代码似乎有一些问题。首先,正如其他人所说,您正在使用带有绑定k &lt; ds.Tables[0].Rows.Count 的索引k,但您正在使用它来对抗ds.Tables[0].Rows[0].ItemArray[k]。它们是两种不同的东西。

最好不要使用这样的索引。您将 LINQ 用于部分代码,但您可以将其用于其余部分。

此外,您似乎不想处理任何一次性物品。您必须确保处理所有一次性用品。

那么,试试这个:

using (var conn = new SqlConnection("Data Source=.; Initial Catalog='TTES'; Integrated Security=SSPI;"))

    using (var da = new SqlDataAdapter("Select AppName from LRNSetting", conn))
    
        using (var ds = new DataSet())
        
            da.Fill(ds,"LRNSetting");

            var appNames =
                ds
                    .Tables[0]
                    .Rows
                    .Cast<DataRow>()
                    .Select(x => x[0].ToString())
                    .ToArray();

            var pro =
                from p in Process.GetProcesses()
                where appNames.Any(x => p.ProcessName.Contains(x))
                select p;
        
    

【讨论】:

【参考方案4】:

简单的 Linq 查询,使 DataRowCollection 可枚举,应用 select 以获取具有进程名称的给定列的列表并与原始进程名称进行比较:

lstprocess.Where(p=>ds.Tables[0].Rows.AsEnumerable.Select(row=>row["ColumnName"].ToString()).Contains(p.ProcessName))

【讨论】:

【参考方案5】:

试试

var pro = from p in lstprocess
          where (p.ProcessName.Contains(ds.Tables[0].Rows[k][0].ToString()))
          select p;

【讨论】:

【参考方案6】:

您需要从循环当前正在迭代的当前行中选择数据。此外,您可能希望从特定列获取数据,因此您需要指定列名,如ds.Tables[0].Rows[k]["columnName"].ToString())。将“columnName”替换为实际的列名。

var pro = from p in lstprocess
          //where p.ProcessName.Contains("LRCDual")
          //where p.ProcessName.Contains(ds.Tables[0].Rows[k].ItemArray)  //added temporary
          where (p.ProcessName.Contains(ds.Tables[0].Rows[k]["columnName"].ToString()))
          select p;

【讨论】:

【参考方案7】:

使用ItemArray[k] 意味着您假设您有k 列,但正如您的代码所示,您有k 行。

所以这一定是你要找的东西:

//Getting all table cells for every column and row as string
var tableValues = ds.Tables[0].AsEnumerable()
                              .SelectMany(i => i.ItemArray.Select(j => j.ToString()))
                              .ToList();

Process[] lstprocess = Process.GetProcesses();

var pro = from p in lstprocess
          where tableValues.Any(i => p.ProcessName.Contains(i))
          select p;

【讨论】:

以上是关于C# 使用 LINQ Query 将记录与进程数组的结果进行比较的主要内容,如果未能解决你的问题,请参考以下文章

如何使用基于 SQL Query 的连接在 C# 中编写 LINQ?

如何使用 LINQ C# 将一个数据表拆分为两个(匹配记录)(不匹配记录)

将 linq 查询转换为字符串数组 - C#

Linq-to-sql 使用 GroupBy 并返回满足条件的记录

如何在 LINQ SQL C# 中返回动态周数?

在 C# 中使用 LINQ 在字符串数组中查找确切的子字符串