Reputation: 4198
I have a simple question, I am converting sql result using liqu to dictionary it looks like this:
result.ExtendedRelationshipSet = reader.Read().AsParallel()
.Select(r =>
new RelationshipsSyncComp.RelationshipCollection.ExtendedRelationship()
{
Id = r.RelationshipId,
FromItemId = r.fromDocumentId,
FromItem = new Item() {Id = r.fromDocumentId},
FromBridgeId = r.fromBridgeId ?? r.fromDocumentId,
FromDocumentKey = r.fromDocumentKey,
}).ToDictionary(x => RelationshipsSyncComp.RelationshipCollection
.RelationshipResultKey(type, x), x => x);
Key for the dictionary is build from combining from id and to id, but I noticed there not unique (some transaction bug that sometimes duplicates record in db), so basically there are duplicated entry's.
Can I check using above procedure if key in the dictionary already exists, or ignore duplicate keys?
Upvotes: 0
Views: 925
Reputation: 5488
You could use Lookup to allow duplicate keys. And use ToLookup method instead of ToDictionary()
If you want to ignore duplicates, you can use DistinctBy before ToDictionary
from morelinq or create your own extension
public static IEnumerable<TSource> DistinctBy<TSource, TKey>
(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
HashSet<TKey> keys = new HashSet<TKey>();
foreach (TSource item in source)
if (keys.Add(keySelector(element)))
yield return item ;
}
And then call it before ToDictionary
result.ExtendedRelationshipSet = reader.Read().AsParallel()
.Select(r =>
new RelationshipsSyncComp.RelationshipCollection.ExtendedRelationship()
{
Id = r.RelationshipId,
FromItemId = r.fromDocumentId,
FromItem = new Item() {Id = r.fromDocumentId},
FromBridgeId = r.fromBridgeId ?? r.fromDocumentId,
FromDocumentKey = r.fromDocumentKey,
})
.DistinctBy(x=> RelationshipsSyncComp.RelationshipCollection.RelationshipResultKey(type, x))
.ToDictionary(x => RelationshipsSyncComp.RelationshipCollection.RelationshipResultKey(type, x), x => x);
Upvotes: 2
Reputation: 415
If you use a .GroupBy() before .ToDictionary() then you can create a dictionary with lists as values.
Upvotes: 0
Reputation: 16956
Option 1 - Take first item in case of duplicate keys.
result.ExtendedRelationshipSet = reader.Read().AsParallel().Select(r => new RelationshipsSyncComp.RelationshipCollection.ExtendedRelationship()
{
Id = r.RelationshipId,
FromItemId = r.fromDocumentId,
FromItem = new Item() {Id = r.fromDocumentId},
FromBridgeId = r.fromBridgeId ?? r.fromDocumentId,
FromDocumentKey = r.fromDocumentKey,
}).GroupBy(g=>RelationshipsSyncComp.RelationshipCollection.RelationshipResultKey(type, x))
.ToDictionary(x => x.Key, x => x.First());
Option 2 - Filter or ignore items having duplicated Key
.
result.ExtendedRelationshipSet = reader.Read().AsParallel().Select(r => new RelationshipsSyncComp.RelationshipCollection.ExtendedRelationship()
{
Id = r.RelationshipId,
FromItemId = r.fromDocumentId,
FromItem = new Item() {Id = r.fromDocumentId},
FromBridgeId = r.fromBridgeId ?? r.fromDocumentId,
FromDocumentKey = r.fromDocumentKey,
}).GroupBy(g=>RelationshipsSyncComp.RelationshipCollection.RelationshipResultKey(type, x))
.Where(e=>e.Count() > 1) // ignore duplicates
.ToDictionary(x => x.Key, x => x.First());
Upvotes: 1