views:

101

answers:

3

C#: I have a collection of objects . T has 2 properties. Property A and Property B. The rule that this collection needs to adhere to is that the combination of values for A and B must be unique within the collection. In other words, A and B need to serve as a composite primary key.

Is there an operation in Linq I can use to check this condition? I'd expect it to be something like

if (items.Select(x => x.Name).Distinct().Count() != items.Select(x => x.Name).Count())

The above statement is how I would check whether there are items in the collection which have duplicate Names, but I don't know how to do it for more than one property.

A: 

You can inject your own equality comparer. Example is here: http://social.msdn.microsoft.com/forums/en-US/linqprojectgeneral/thread/c5b71644-b2d9-422b-b7fe-ef3bef30bbac/

Vitaliy Liptchinsky
Be careful here. Custom comparers are fine for LINQ to objects, but will throw a run-time exception in LINQ to SQL or Entity Framework.
Cylon Cat
+9  A: 

Use an anonymous type to select the composite key, e.g.

int totalCount = items.Count();
int distinctCount = items.Select(x => new { x.Name, x.Other })
                         .Distinct()
                         .Count();

Anonymous types automatically implement equality and hashcodes based on their properties (and the default equality comparer for the types of those properties).

Jon Skeet
A: 

Simply select into a new, anonymous object

var keys = items.Select( x => new { x.Name, x.Other } ).ToList();

if (keys.Distinct().Count() != keys.Count())
{
 ...
}
tvanfosson