我编写了以下代码来比较数据集的记录(即一列的记录)。我收到以下异常:
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;
}
}
虽然您在
ds.Tables[0].Rows.Count
上进行了迭代,但是您使用的是 ItemArray
计数器,而不是预期的 Rows
计数器,
ds.Tables[0].Rows[0].ItemArray[k].ToString()
我建议你检查一下你的逻辑
您的代码似乎存在一些问题。首先,正如其他人所说,您将索引
k
与绑定 k < ds.Tables[0].Rows.Count
一起使用,但您将其用于针对 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;
}
}
}
简单的 Linq 查询,使 DataRowCollection 可枚举,应用 select 来获取具有进程名称的给定列的列表,并与原始进程名称进行比较:
lstprocess.Where(p=>ds.Tables[0].Rows.AsEnumerable.Select(row=>row["ColumnName"].ToString()).Contains(p.ProcessName))
您需要检查您的代码。
您对表的行计数进行了迭代,但您使用的是 ItemArray 的计数器,而不是预期的行计数器。
替换此代码
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['ColumnName'].ToString()))
select p;
尝试
var pro = from p in lstprocess
where (p.ProcessName.Contains(ds.Tables[0].Rows[k][0].ToString()))
select p;
您需要从循环当前迭代的当前行中选择数据。此外,您可能希望从特定列获取数据,因此您需要指定列名称,如
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;
使用
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;