1

I have a very basic sql view which joins 3 tables: users, pictures, and tags.

How would one create the query below in a way that it won't list the same pictures more than once? In other words, I want to Group By pictures (I think) and return get the first insance of each.

I think this is very similar to the post Linq Query Group By and Selecting First Items, but I cannot figure out how to apply it in this case where the query is instantiating MyImageClass.

        validPicSummaries = (from x in db.PicsTagsUsers
         where x.enabled == 1
           select new MyImageClass { 
               PicName = x.picname, 
               Username= x.Username, 
               Tag = x.tag }).Take(50);
Community
  • 1
  • 1
Dave
  • 4,949
  • 6
  • 50
  • 73

1 Answers1

3

To exclude duplicates, you can use the Distinct LINQ method:

validPicSummaries =
   (from x in db.PicsTagsUsers
    where x.tag == searchterm && x.enabled == 1
    select new MyImageClass
    { 
       PicName = x.picname, 
       Username= x.Username, 
       Tag = x.tag
    })
    .Distinct()
    .Take(50);

You will need to make sure that the objects are comparable so that two MyImageClass objects that have the same PicName, Username, and Tag are considered equal (or however you wish to consider two of them as being equal).

You can write a small class that implements IEqualityComparer<T> if you would like to have a custom comparer for just this case. Ex:

  private class MyImageClassComparer : IEqualityComparer<MyImageClass>
  {
     public bool Equals(MyImageClass pMyImage1, MyImageClass pMyImage2)
     {
        // some test of the two objects to determine 
        // whether they should be considered equal

        return pMyImage1.PicName == pMyImage2.PicName
           && pMyImage1.Username == pMyImage2.Username
           && pMyImage1.Tag == pMyImage2.Tag;
     }

     public int GetHashCode(MyImageClass pMyImageClass)
     {
        // the GetHashCode function seems to be what is used by LINQ
        // to determine equality. from examples, it seems the way
        // to combine hashcodes is to XOR them:

        return pMyImageClass.PicName.GetHashCode()
           ^ pMyImageClass.UserName.GetHashCode()
           ^ pMyImageClass.Tag.GetHashCode();
     }
  }

Then when you call distinct:

    ...
    .Distinct(new MyImageClassComparer())
    .Take(50);
Dave Cousineau
  • 12,154
  • 8
  • 64
  • 80
  • Wouldn't I need to exclude Tag so that I just get the first instance of the pic, if it has many tags? looks good, like I overlooked the obvious solution. I will get back momentarily... – Dave May 07 '13 at 00:44
  • @Dave I'm not sure of the meaning of the properties. It's up to you how to consider them to be duplicate. – Dave Cousineau May 07 '13 at 00:48