我如何使用两个其他列值的两个值获取DataTable Row的索引?

时间:2014-03-06 08:27:42

标签: c# asp.net linq datatable rows

致我的申请:

我有两个DataTables,我想把第一个DataTable过滤掉。为此我从第一个DataTable获取列user和modul,如果第二个不存在,我添加一个新行。

这是我的第二个DataTable的结构:

User | Modul | Time | Department | Status 

我想检查两个列(User和Modul)是否存在第二个DataTable中包含此值的行。如果条目存在,我需要行索引。我怎么能用Linq做到这一点? 我的第二个DataTable的名称是analyse_table。

这里是我的代码:

private static DataTable FilterDataTable(DataTable nofilter_datatable) 
        {
            DataTable analyse_table = new DataTable("Filter_Analyse");

            DataColumn User = new DataColumn("User", typeof(string));
            DataColumn Modul = new DataColumn("Modul", typeof(string));
            DataColumn TIME = new DataColumn("TIME", typeof(string));
            DataColumn Department = new DataColumn("Department", typeof(string));
            DataColumn Status = new DataColumn("Status", typeof(string));

            analyse_table.Columns.Add(User);
            analyse_table.Columns.Add(Modul);
            analyse_table.Columns.Add(TIME);
            analyse_table.Columns.Add(Department);
            analyse_table.Columns.Add(Status);

            foreach (DataRow nf_row in nofilter_datatable.Rows)
            {
                string user = nf_row["User"].ToString();
                string modul = nf_row["Modul"].ToString();

                string OUT = nf_row["OUT"].ToString();
                string IN = nf_row["IN"].ToString();

                bool contains_user = analyse_table.AsEnumerable()
                    .Any(row => user == row.Field<string>("User"));

                bool contains_modul = analyse_table.AsEnumerable()
                    .Any(Row => modul == Row.Field<string>("Modul"));

                if (!contains_user || !contains_modul)
                {
                    try
                    {
                        DataRow row = analyse_table.NewRow();

                        row["User"] = user;
                        row["Modul"] = modul;

                        if (OUT != string.Empty)
                        {
                            row["TIME"] = OUT;
                            row["Status"] = "OUT";
                        }
                        else if (IN != string.Empty)
                        {
                            row["TIME"] = IN;
                            row["Status"] = "IN";
                        }

                        string[] userSpli = user.Split('@');

                        row["Department"] = GetActiveDirectoryAttribute(userSpli[0], "Department", domaincontroller);

                        analyse_table.Rows.Add(row);
                    }
                    catch (Exception)
                    {

                    }

                }

                if (contains_user && contains_modul)
                {
                    //index??

                    //string status = analyse_table.Rows[0]["Status"].ToString();

                }


            }

            return analyse_table;

        }

我需要帮助。

2 个答案:

答案 0 :(得分:2)

无需知道analyse_table中的索引,使用FirstOrDefault应该允许您直接找到所需的行

var rowUser = analyse_table.AsEnumerable()
                      .FirstOrDefault(row => user == row.Field<string>("User"));

var rowModul = analyse_table.AsEnumerable()
                .FirstOrDefault(Row => modul == Row.Field<string>("Modul"));

if (rowUser == null || rowModul == null)
{

   // Not exist so I add a new row 
}
if (rowUser != null && rowModul != null)
{
     string statusUser = rowUser["Status"].ToString();
     string statusModul = rowModul["Status"].ToString();

}

但是,执行了两个不同的查询来搜索您的行,我们无法保证这两行是相同的。因此,您可能需要更改代码以在同一行中搜索用户和模块

var rowResult = analyse_table.AsEnumerable()
                .FirstOrDefault(row => (user == row.Field<string>("User") && 
                                        modul == row.Field<string>("Modul"));

if(rowResult == null)
    // add new
else
    // read status

答案 1 :(得分:0)

我假设您要添加第一个表中但不在第二个表中的所有缺失行,这些行通过两列User + Modul标识。

您可以使用“LEFT OUTER JOIN”链接包含这些列的匿名类型上的两个表。这样效率更高。

 var newRowsInFirst = from r1 in first_table.AsEnumerable()
                     join r2 in analyse_table.AsEnumerable()
                     on   new { User=r1.Field<string>("User"), Modul=r1.Field<string>("Modul") }
                     equals new { User=r2.Field<string>("User"), Modul=r2.Field<string>("Modul") }
                     into gj from g2 in gj.DefaultIfEmpty()
                     where g2 == null
                     select r1;

然后使用简单的foreach - 循环来添加这些行。

foreach(var newRow in newRowsInFirst)
{
    analyse_table.ImportRow(newRow);
    // or:
    //DataRow addedRow = analyse_table.Rows.Add();
    //addedRow.ItemArray = newRow.ItemArray;
}