How to use IEqualityComparer

I have several bells in my database with the same number. I want to get all of them without duplication. Then I create a comparison class to do the job, but the execution of the function makes a big delay from the function without a clear, from 0.6 s to 3.2 s!

Am I doing it right or do I need to use a different method?

reg.AddRange((from a in this.dataContext.reglements join b in this.dataContext.Clients on a.Id_client equals b.Id where a.date_v <= datefin && a.date_v >= datedeb where a.Id_client == b.Id orderby a.date_v descending select new Class_reglement { nom = b.Nom, code = b.code, Numf = a.Numf, }).AsEnumerable().Distinct(new Compare()).ToList()); class Compare : IEqualityComparer<Class_reglement> { public bool Equals(Class_reglement x, Class_reglement y) { if (x.Numf == y.Numf) { return true; } else { return false; } } public int GetHashCode(Class_reglement codeh) { return 0; } } 
+63
c # linq iequalitycomparer
Jul 14 2018-11-14T00:
source share
4 answers

Unsurprisingly, given your implementation of GetHashCode , which always returns the same value. Distinct relies on a good hash function to work efficiently.

When implementing class interfaces, you need to read the documentation first , otherwise you do not know what contract you intend to implement. one

In your code, the solution should forward GetHashCode to Class_reglement.Numf.GetHashCode and implement it accordingly.

In addition, your Equals method is filled with unnecessary code. It could be rewritten as follows (the same semantics, 1/4 of the code, more readable):

 public bool Equals(Class_reglement x, Class_reglement y) { return x.Numf == y.Numf; } 

In addition, the ToList call ToList not needed and takes a lot of time: AddRange accepts any IEnumerable , so conversion to List not required. AsEnumerable also redundant here, since processing the result in AddRange will still result in this.




1 The implementation of the code, not knowing what it actually does, is called cult programming of the load . This is a surprisingly common practice. This basically does not work.

+144
Jul 14 2018-11-11T00:
source share

Try this code:

 public class GenericCompare<T> : IEqualityComparer<T> where T : class { private Func<T, object> _expr { get; set; } public GenericCompare(Func<T, object> expr) { this._expr = expr; } public bool Equals(T x, T y) { var first = _expr.Invoke(x); var sec = _expr.Invoke(y); if (first != null && first.Equals(sec)) return true; else return false; } public int GetHashCode(T obj) { return obj.GetHashCode(); } } 

An example of its use:

 collection = collection .Except(ExistedDataEles, new GenericCompare<DataEle>(x=>x.Id)) .ToList(); 
+28
May 13 '14 at 6:15
source share

Enabling your comparison class (or, more specifically, calling AsEnumerable , which you need to use to work it) means that the sorting logic has moved from the database to the database client (your application). This meant that your client now needs to receive and process a larger number of records, which will always be less effective if you search in a database where appropriate indexes can be used.

You should try to develop a where clause that suits your requirements instead, see Using IEqualityComparer with LINQ to Entities Except for a suggestion for more details.

+2
Jul 14 2018-11-11T00:
source share

Just code with GetHashCode implementation and NULL checks:

 public class Class_reglementComparer : IEqualityComparer<Class_reglement> { public bool Equals(Class_reglement x, Class_reglement y) { if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null)) return false; return x.Numf == y.Numf; } public int GetHashCode(Class_reglement product) { //Check whether the object is null if (Object.ReferenceEquals(product, null)) return 0; //Get hash code for the Numf field if it is not null. int hashNumf = product.hashNumf == null ? 0 : product.hashNumf.GetHashCode(); return hashNumf; } } 

Example: Class_reglement list is different Numf

 List<Class_reglement> items = items.Distinct(new Class_reglementComparer()); 
+1
Oct 23 '17 at 5:21 on
source share



All Articles