Solved

Get uniqe property list from ObservableCollection using Linq

Posted on 2011-02-26
25
2,739 Views
Last Modified: 2013-11-11
I have a object model that has ID, Name and Category properties

I have another object model that is an ObservableCollection of my first model

I want to get all the unique categories from my collection using Linq, but I am not sure how to do it...

I was using something like:

            var sel = (from i in items
                      select new
                      {
                          i.Category
                      }).Distinct();

but I am getting a null value from it (there are 1000 test records in the collection all with categories)


New to Linq, so I am not sure what I am doing wrong.
0
Comment
Question by:S7up1d
  • 11
  • 9
  • 3
  • +1
25 Comments
 
LVL 42

Expert Comment

by:sedgwick
ID: 34990487
what is the type of Category?
0
 

Author Comment

by:S7up1d
ID: 34990517
Sorry, should have included that....

Category is string
0
 
LVL 42

Expert Comment

by:sedgwick
ID: 34990672
the linq expression is correct.
if u remove the Disticnt() call, do u get all categories?
0
Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

 

Author Comment

by:S7up1d
ID: 34990940
I get nothing...  I get this error:

System.Collections.Generic.IEnumerator<TSource>.Current = Could not evaluate expression
0
 
LVL 42

Expert Comment

by:sedgwick
ID: 34990946
ok, so we need to go one step back and examine the items collection.
if you debug the code and "Watch" the items collection, can u view its items?
how do u fill the items collection?
0
 
LVL 63

Assisted Solution

by:Fernando Soto
Fernando Soto earned 500 total points
ID: 34991826
Hi S7up1d;

Code like this works.

ObservableCollection<MyObjectModel> MyObservable = new ObservableCollection<MyObjectModel>( );
// Initialize the ObservableCollection MyObservable here
// ...

// Linq query using MyObservable collection of MyObjectModel
var sel = (from i in MyObservable
           select new 
           {
               i.Category
           }).Distinct();

// Iterate through the collection
foreach( var s in sel )
{
    Console.WriteLine( s.Category );
}

// ...

public class MyObjectModel
{
    public int ID { get; set; }
    public string Name { get; set; }
    public string Category { get; set; }
}

Open in new window


Note in my code I am using the ObservableCollection of type MyObjectModel in the query. Is your code is items variable of  ObservableCollection of type MyObjectModel? If it is can you please post your code as I did so that we can see the whole picture.

Thank
Fernando
0
 

Author Comment

by:S7up1d
ID: 34992285
so, the code I had was working, I was misinterpreting the errors and not iterating through the collection to check it.  A bit hairbrained on my part.

The last part of this is that I cannot get it to return the observable collection of properties as an observable collection... I get invalid cast exception when I use:


                    categories = (ObservableCollection<string>)(  from i in items
                                                                  select new
                                                                  {
                                                                    i.Category
                                                                  }).Distinct();


0
 
LVL 63

Assisted Solution

by:Fernando Soto
Fernando Soto earned 500 total points
ID: 34992365
Hi S7up1d;

There is no direct conversion to an ObservableCollection from Linq. So this is what you need to do:

IEnumerable<string> sel = 
    ( from i in MyObservable
      select 
          i.Category
    ).Distinct( );

ObservableCollection<string> categories = new ObservableCollection<string>(sel);

Open in new window


That should give you an ObservableCollection of Strings.

Fernando
0
 

Assisted Solution

by:S7up1d
S7up1d earned 0 total points
ID: 34992469
I tried this:

                   IEnumerable<string> distinctCategories = (from i in items
                                                                  select
                                                                    i.Category
                                                            ).Distinct();

                    categories = new ObservableCollection<string>(distinctCategories);  



I get the IEnumerable<string> but when I try to assign the categories to a new ObservableCollection<string> it will not go as there is no constuctor that accepts a single argument.  

Is there another way to convert this or do I have to just use the IEnumerable?
0
 
LVL 63

Expert Comment

by:Fernando Soto
ID: 34992495
What data type is categories?
0
 
LVL 63

Expert Comment

by:Fernando Soto
ID: 34992501
BTW I just test the code I posted to you and it does work on my system.
0
 

Author Comment

by:S7up1d
ID: 34992596
ObservableCollection<string> categories;

0
 
LVL 63

Expert Comment

by:Fernando Soto
ID: 34992668
Hi S7up1d;

Can you please post all the pertinent code copied from your project and past here so I can have a look. As I stated I have tested this code and it does work.

The three overloaded constructors for the ObservableCollection<T> from Microsoft Documentation:
ObservableCollection<T>()
ObservableCollection<T>(IEnumerable<T>)
ObservableCollection<T>(List<T>)               // The one used in the example above

Open in new window


Fernando
0
 
LVL 63

Expert Comment

by:Fernando Soto
ID: 34992681
What version of .Net and C# are you using?
0
 
LVL 63

Expert Comment

by:Fernando Soto
ID: 34992708
Hi S7up1d;

It appears that in .Net version 3.5 the ObservableCollection only had the default constructor and the reason for the error you are getting. Try this version of the code to get what you need.

IEnumerable<string> sel = 
    ( from i in MyObservable
      select 
          i.Category
    ).Distinct( );

ObservableCollection<string> categories = new ObservableCollection<string>();

foreach( string c in sel )
{
    categories.Add( c );
}

Open in new window


Fernando
0
 
LVL 63

Expert Comment

by:Fernando Soto
ID: 34999200
Has my last post corrected the issue?
0
 
LVL 12

Expert Comment

by:kumar754
ID: 35021217
well, I thought .NET 3.5 also has the same 3 constructors asin .NET 4.0

Reference:
http://msdn.microsoft.com/en-us/library/ms658737(v=VS.90).aspx

check your using/imports namespace

using System.Collections.ObjectModel;


Also, if you are using .net 3.0, then try convert it to List instead of IEnumerable and then pass to Observable Collection


List<string> sel =
    ( from i in MyObservable
      select
          i.Category
    ).Distinct();

ObservableCollection<string> categories = new ObservableCollection<string>(sel);
0
 

Author Comment

by:S7up1d
ID: 35021504
I am using .NET 4.0 CF for Windows Phone.  

While I can iterate through the list or the ienumerable and then copy into the ObservableCollection, I would rather not, I would imagine that there is a better way to do that than having two copies of the list in memory during the transfer process.

0
 
LVL 63

Expert Comment

by:Fernando Soto
ID: 35021617
@ kumar754;

Following your link shows the three constructors. Investigating a little bit more by clicking on "ObservableCollection<T> Class" just below the three constructors definition you will find the Change History as shown in the image below. So in version 3.5 just default constructor and in version 3.5 SP1 added new constructors.

Fernando Change History
0
 
LVL 12

Expert Comment

by:kumar754
ID: 35021885
@FernandoSoto

Thanks buddy, for the sharing this information. Yeah you are right, they added in 2008, good to know that I am using the same SP1 version.
0
 
LVL 63

Expert Comment

by:Fernando Soto
ID: 35022002
Hi S7up1d;

If you can upload the project and all its files I will attempt to see what is happening. If you can follow the instructions below.

To upload a file in zip format to the Experts Exchange Stuff web site at http://www.ee-stuff.com follow these steps:

1.  Zip the files or project to be uploaded
2.  The go to http://www.ee-stuff.com
3.  If you are prompted to log in use the same username and password you use on the main site here
4.  At the top of the page click on "Expert Area" tab
5.  Then click on "Upload a new file" link
6.  Follow the instructions on the page
7.  After a successful upload post the link of the file in the question.

Fernando
0
 

Author Comment

by:S7up1d
ID: 35047200
I am using .NET 4.0 For WINDOWS PHONE

not 3.5...

I will have to rewrite some of the code into an example I can post here.
0
 

Accepted Solution

by:
S7up1d earned 0 total points
ID: 35833628
I did not ever get an answer for this question that was even using the correct framework.
0
 
LVL 63

Expert Comment

by:Fernando Soto
ID: 35834270
You should of continued to work with us and follow through with your response from post 03/06/11 02:18 PM, ID: 35047200.
0
 

Author Closing Comment

by:S7up1d
ID: 35872711
Not on the correct framework at all, but I do want to give the points for the work done.

Thanks for your help!!!
0

Featured Post

MIM Survival Guide for Service Desk Managers

Major incidents can send mastered service desk processes into disorder. Systems and tools produce the data needed to resolve these incidents, but your challenge is getting that information to the right people fast. Check out the Survival Guide and begin bringing order to chaos.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Many of us here at EE write code. Many of us write exceptional code; just as many of us write exception-prone code. As we all should know, exceptions are a mechanism for handling errors which are typically out of our control. From database errors, t…
Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
This video shows how to use Hyena, from SystemTools Software, to bulk import 100 user accounts from an external text file. View in 1080p for best video quality.
Established in 1997, Technology Architects has become one of the most reputable technology solutions companies in the country. TA have been providing businesses with cost effective state-of-the-art solutions and unparalleled service that is designed…

839 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question