-2

I am doing an except of two DataTables in . I've overloaded the IEqualityComparer

public bool Equals(T sourceRec, T targetRec)
    {
        string srcHash, tgtHash;
        srcHash = HashGenerator.GenerateHash<T>(sourceRec);
        tgtHash = HashGenerator.GenerateHash<T>(targetRec);
        return srcHash.Equals(tgtHash);
    }

    public int GetHashCode(T obj)
    {
        return base.GetHashCode();
    }

and except will work by taking into consideration of the Hash value of each DataRow.

public class CompareResult<T>
    {
        public IEnumerable<T> Inserted_Updated;
        public IEnumerable<T> Updated;
        public IEnumerable<T> Deleted;
    }

 public CompareResult<DataRow> Compare(DataTable source, DataTable target)
        {
            CompareResult<DataRow> rest = new CompareResult<DataRow>();
            rest.Inserted_Updated = target.AsEnumerable().Except(source.AsEnumerable(), RowHashComparer);
            rest.Deleted = (source.AsEnumerable().Except(target.AsEnumerable(), RowHashComparer)).Except(target.AsEnumerable().Except(source.AsEnumerable(), RowHashComparer));

            return rest;
        }

CompareResult<DataRow> strResult = SD1.Compare(src, tgt);

RowHashComparer is as a property used to perform custom except by comparing Hash codes. What i tracked down is the equality comparison is actually happening after the Except method has returned.

Please suggest.

  • Instead of returning an `Enumerable`, you could return a `HashSet<>`. – Rob Jun 27 '17 at 06:18
  • 3
    I have a bag full of marbles, I want to know how many marbles I have. Can you tell me a way that doesn't involve *counting* them one by one? Well, no, not really. Maybe you should take a step back and ask yourself if a bag is what you really need. Does some other type of collection do a better job? – InBetween Jun 27 '17 at 06:21
  • 1
    @InBetween - money can be counted by weighting it. Standardized marbles in a bag with a known weight can be counted with a scale. – Moho Jun 27 '17 at 06:29
  • @Moho exactly, but then its not an `Enumerable` any more. You need additional tools, the bag by itself is not enough. – InBetween Jun 27 '17 at 06:30
  • Can you paste the code of your overload? Maybe you can do some administration there. – brijber Jun 27 '17 at 06:33
  • @Vineet Alampally Please share your code so i can work out. – Rohit Poudel Jun 27 '17 at 06:36
  • @RohitPoudel I've improved the question, please have a look. – Vineet Alampally Jun 27 '17 at 06:58
  • @brijber please have a look at the improved question – Vineet Alampally Jun 27 '17 at 06:58
  • If you're using a `DataTable` why not just do `table.Where(row => row.RowState == DataRowState.Added || row.RowState == DataRowState.Modified);`? – brijber Jun 27 '17 at 07:07
  • @brijber i have to bring out the set difference between two tables. – Vineet Alampally Jun 27 '17 at 07:14
  • @Vineet Alampally cant we convert datatable to List – Rohit Poudel Jun 27 '17 at 07:23
  • @RohitPoudel yes, we can. But ToList() takes a lot of time. My dataset is huge one. – Vineet Alampally Jun 27 '17 at 07:28
  • @Vineet Alampally If you're using .NET 3.5, you can use you can use `DataTableExtensions.AsEnumerable`(an extension method) and then if you really need a `List` instead of just `IEnumerable' you can call 'Enumerable.ToList:` `IEnumerable sequence = dt.AsEnumerable(); ` or `using System.Linq;` ... `List list = dt.AsEnumerable().ToList();` – Rohit Poudel Jun 27 '17 at 07:33
  • @RohitPoudel I have tried that already, Enumerable.ToList() is taking a lot of time. My datatable has around 200K rows. – Vineet Alampally Jun 27 '17 at 08:38
  • @RohitPoudel I've tracked down the problem, realized that the problem is something else. I've improved the question. Please have a look and suggest. – Vineet Alampally Jun 27 '17 at 13:24
  • @brijber I've tracked down the problem, realized that the problem is something else. I've improved the question. Please have a look and suggest. – Vineet Alampally Jun 27 '17 at 13:24
  • @Vineet Alampally better if we can do this on stored procedure if possible – Rohit Poudel Jun 27 '17 at 13:32

1 Answers1

-3

The simplest form would be:

public static int Count(this IEnumerable source)
{
    int c = 0;
    using (var e = source.GetEnumerator())
    {
        while (e.MoveNext())
            c++;
    }
    return c;
}

we can then improve on this by querying for ICollection:

public static int Count(this IEnumerable source)
{
    var col = source as ICollection;
    if (col != null)
        return col.Count;

    int c = 0;
    using (var e = source.GetEnumerator())
    {
        while (e.MoveNext())
            c++;
    }
    return c;
}
Rohit Poudel
  • 1,793
  • 2
  • 20
  • 24