Question

To My Application:

I have two DataTables and I want to filter out the first DataTable to the second. For this I get the columns user and modul from the first DataTable and if it not exist in the second I add a new row.

This is the structure from my second DataTable:

User | Modul | Time | Department | Status 

and I want to check two Columns (User and Modul) whether the row with this values in the second DataTable exist. If the Entry Exist I need the row index. How I can do this with Linq? The name of my second DataTable is analyse_table.

here my code:

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;

        }

I need help.

Was it helpful?

Solution

There is no need to know the index in the analyse_table, using FirstOrDefault should allow you to find directly the row required

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();

}

However, having executed two different queries to search for your rows, we have no guarantees that the two rows are the same. So perhaps you need to change your code to search for both user and modul in the same row

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

OTHER TIPS

I assume you want to add all missing rows that are in the first table but not in the second, the rows are identified via two columns User + Modul.

You could use a "LEFT OUTER JOIN" to link both tables on an anonymous type containing these columns. This is much more efficient.

 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;

Then use a simple foreach-loop to add these rows.

foreach(var newRow in newRowsInFirst)
{
    analyse_table.ImportRow(newRow);
    // or:
    //DataRow addedRow = analyse_table.Rows.Add();
    //addedRow.ItemArray = newRow.ItemArray;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top