【问题标题】:How I get the index of a DataTable Row with two calues of two other Column Values?如何获得具有两个其他列值的两个值的数据表行的索引?
【发布时间】:2014-03-06 08:27:42
【问题描述】:

到我的应用程序:

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

这是我的第二个数据表的结构:

User | Modul | Time | Department | Status 

我想检查两个列(用户和模块)是否存在第二个 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;

        }

我需要帮助。

【问题讨论】:

  • 如果两个搜索都返回 true,则不清楚要更新哪一行。通过两次单独搜索找到的行不能相同
  • 您的代码做了一些不同的事情,它只是检查是否存在任何用户或任何模块,否则它将添加该行。但它不检查用户和模块是否属于同一行,这是需要的吗?
  • 我想要 DataTable analyse_table 的行索引,其中 User Column 的值是一样的,字符串 user 和 Modul Column 的值是一样的字符串 modul。
  • 我已经更新了……现在你可以看到完整的方法了。

标签: c# asp.net linq datatable rows


【解决方案1】:

无需知道analyze_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();

}

但是,在执行了两个不同的查询来搜索您的行后,我们无法保证这两行是相同的。因此,也许您需要更改代码以在同一行中搜索 user 和 modul

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

【讨论】:

  • 这段代码很好......我可以工作但我现在测试它。
【解决方案2】:

我假设您要添加第一个表中但第二个表中没有的所有缺失行,这些行通过两列 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-loop 来添加这些行。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-23
    • 1970-01-01
    • 1970-01-01
    • 2020-06-03
    • 1970-01-01
    • 1970-01-01
    • 2017-12-29
    相关资源
    最近更新 更多