Using LINQ Distinct in C #

I have a problem using distinct in LINQ. I have this list:

 LineIdChanged LineId OldGatewayPCId NewGatewayPCId LineStringID PlantID 1 93 83 88 160 2 2 93 83 88 161 2 3 94 82 87 162 2 4 94 82 87 163 2 

I tried to get an excellent LineId value, so in this case I should only get two objects instead of all four objects. I tried this:

  var s = (from n in _dataBaseProvider.SelectPjdGatewayLineChanged(selectedSourcePlant.LPS_Database_ID) select new PjdGatewayLineChanged() { LineId = n.LineId, LpsLineNo = n.LpsLineNo, LineIdChanged = n.LineIdChanged}).Distinct(); LinesOld = s.ToList(); 

But it gives me all 4 objects.

+4
source share
4 answers

You need to use MoreLINQ DistinctBy :

 var s = (from n in _dataBaseProvider.SelectPjdGatewayLineChanged (selectedSourcePlant.LPS_Database_ID) select new PjdGatewayLineChanged { LineId = n.LineId, LpsLineNo = n.LpsLineNo, LineIdChanged = n.LineIdChanged }) .DistinctBy(p => p.LineId); 
+4
source

what your problem is that LINQ and the .Net framework component know how to distinguish between different objects like PjdGatewayLineChanged . therefore, it uses the standard thing, which is to look for equality in terms of memory references.

So what you need to do is use the second overload of this method and provide IEqualityComparer

see here

 Distinct<TSource>(IEnumerable<TSource>, IEqualityComparer<TSource>) 

so LINQ knows how to compare diff instances of type PjdGatewayLineChanged
msdn link IEqualityComparer

0
source

If you think that all lines are equal, if they have equal fields:

 var s = (from p in _dataBaseProvider.SelectPjdGatewayLineChanged(selectedSourcePlant.LPS_Database_ID) select new PjdGatewayLineChanged() { LineId = p.LineId, LpsLineNo = p.LpsLineNo, LineIdChanged = p.LineIdChanged }) .GroupBy(p => p.LineId) .Select(p => p.First()); 

You group your identifier, and then for each group you take the first line.

or, more compact,

 var s = from p in _dataBaseProvider.SelectPjdGatewayLineChanged(selectedSourcePlant.LPS_Database_ID) group p by p.LineId into q let r = q.First() select new PjdGatewayLineChanged() { LineId = r.LineId, LpsLineNo = r.LpsLineNo, LineIdChanged = r.LineIdChanged }; 

Thus, the creation of PjdGatewayLineChanged was carried over to the last step (after choosing the right groupby β€œcandidate”.

0
source

That's what. The Distinct (IEnumerable) method returns an unordered sequence that does not contain duplicate values. To compare values, the default equality mapping, Default, is used .

There are two uses for .Distinct() with your custom types:

  • provide your GetHashCode and Equals methods for PjdGatewayLineChanged .
  • Use Overloaded Distinct with its Custom Equality Comparer

For more information, check the MSDN for Distinct, check the MSDN for Distinct, you will find good documentation code snippets to help you implement the required functionality.

0
source

Source: https://habr.com/ru/post/1495305/


All Articles