3

I want to check if under column "name" is there any same value. If yes so i want to check if the next same value > Bit + Size. I can do it with 2 for loops but what i want is something more simple. Can anyone show me how?

My DataTable:

name    Bit    Size
m1      8       3
m0      9       5
m1      10      2    // Error, should be 11
m2      11      4

My code:

for(int i = 0; i <= Dt.Rows.Count - 1; i++)
{
    for(int y = i +1; y <= Dt.Rows.Count - 1, y++ )
      {
          if(Dt.Rows[i]["name"].ToString() == Dt.Rows[y]["Name"].ToString())
                if( (Convert.ToInt32(Dt.Rows[i]["Bit"].ToString()) + Convert.ToInt32(Dt.Rows[i]["Size"].ToString()) > (Convert.ToInt32(Dt.Rows[y]["Bit"].ToString())   ) )
                    {
                         // Show Error
                         MessageBox.Show("Error");
                         Dt.Rows[y]["Bit"] = Dt.Rows[i]["Bit"];
                    }
      } 
}  
Le Viet Hung
  • 489
  • 4
  • 10
  • 21
  • I don't know how large your db is, but you could use GroupBy(x => x.name).Count() to see which are above 1. Than u know which names are being used multiple times – user1797792 Jan 15 '13 at 11:44

2 Answers2

3

For what it's worth, this is the Linq approach:

var invalidGroups = DT.AsEnumerable()
    .GroupBy(r => r.Field<string>("name"))
    .Where(g => g.Count() > 1)
    .Select(g => new { Name = g.Key, FirstRow = g.First(), Group = g })
    .Select(x => new { x.Name, x.FirstRow, x.Group, FirstSum = x.FirstRow.Field<int>("Bit") + x.FirstRow.Field<int>("Size") })
    .Where(x => x.Group.Any(r => x.FirstSum < r.Field<int>("Bit") + r.Field<int>("Size")));
foreach (var x in invalidGroups)
{
    string name = x.Name;
    DataRow referenceRow = x.FirstRow;
    var invalidRows = x.Group
        .Where(r => x.FirstSum < r.Field<int>("Bit") + r.Field<int>("Size"));
    foreach (DataRow r in invalidRows)
    {
        int sum = r.Field<int>("Bit") + r.Field<int>("Size"); // 12 instead of 11
        r.SetField("Bit", referenceRow.Field<int>("Bit"));
        r.SetField("Size", referenceRow.Field<int>("Size"));
    }
}

As you can see, it's not really shorter, but probably more maintainable or readable.

Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
  • thanks Tim, it looks great, but what i want is something shorter :) but thanks anyway – Le Viet Hung Jan 15 '13 at 12:07
  • @LeVietHung: I can make it a one-liner and remove descriptive/informative lines :-P Note that not the length matters but readability and (with reservations) efficiency. – Tim Schmelter Jan 15 '13 at 12:10
0

Try this in SQL

select b.name, b.bits + b.size
from Table_1 b 
where exists (select name from Table_1 a where a.name = b.name group by name having count(*) > 1)
group by b.name, b.bits + b.size
having count(*) = 1
Max
  • 6,821
  • 3
  • 43
  • 59