Reputation: 89
I have two collections of my object models that I am comparing for inequality on a per-property basis.
ObservableCollection<LayerModel> SourceDrawingLayers
...and:
ObservableCollection<LayerModel> TargetDrawingLayers
I have received great advice on creating the non-equijoin LINQ query in general and have it working in my application to great effect but now I would like to speed it up:
var onOffQuery = from target in TargetDrawingLayers
from source in SourceDrawingLayers
where target.Name == source.Name && target.OnOff != source.OnOff
select target;
My understanding is I am multiplying my query by the number of items in the source drawing *
the number of items in the target drawings *
the number of target drawings that I populated into TargetDrawingLayers
.
I would like to speed up this operation using Join
but I'm running into issues with the !=
part of it.
I played around with this:
var newQuery = from source in SourceDrawingLayers
join target in TargetDrawingLayers
on target.name
where target.OnOff != source.OnOff
select target;
But I'm struggling with the syntax. Can someone set me on the right track with it?
Also, will this even be a noticeable performance improvement?
Upvotes: 3
Views: 546
Reputation: 43495
Maybe what you need is to join on the combination of the properties Name
and OnOff
. The combination can be expressed as a ValueTuple
:
var newQuery = from source in SourceDrawingLayers
join target in TargetDrawingLayers
on (source.Name, source.OnOff) equals (target.Name, !target.OnOff)
select target;
Upvotes: 0
Reputation: 62213
Replace on target.name
with on source.name equals target.name
var newQuery = from source in SourceDrawingLayers
join target in TargetDrawingLayers
on source.name equals target.name
where target.OnOff != source.OnOff
select target;
In Linq-to-objects the join will create a Lookup<TKey,TElement>
on the join properties which will result in a performance improvement when matching the source
and target
. Assuming that this results on a restricted result set it should improve the original code quit a bit. Of course if it results in many matches because name
contains a very limited range of values on both sides then the performance will not be effected much at all.
As a reference please see the link to the Enumerable.cs source code that was provided in the comments below by juharr.
Upvotes: 5