Solved

Cannot order by type '<>f__AnonymousType0`1[System.String]'. c# LINQ

Posted on 2014-11-15
35
593 Views
Last Modified: 2016-02-16
In the following code, I get Cannot order by type '<>f__AnonymousType0`1[System.String]'. at line 5 at foreach.

Question 1: How can I correct this?

       dynamic outputs = (from output in wscgsContext.Searches
                         group output by new { Key = output.City } into cityGroup
                           select cityGroup.Key).Distinct();//.OrderBy(c => c);

        foreach (String output in outputs)
        {
            cmbCity.Items.Add(output);
        }

Open in new window


And, with .OrderBy(c => c); included, I get:
Cannot convert type '<>f__AnonymousType0<string>' to 'string' at foreach (String output in outputs)

Question 2: How can make it work with distinct?
0
Comment
Question by:Mike Eghtebas
  • 14
  • 10
  • 9
  • +1
35 Comments
 
LVL 9

Expert Comment

by:Valliappan AN
ID: 40444681
As i understand when you put the keyword new , you create anonymous type, can you try without the new casting.
0
 
LVL 62

Expert Comment

by:Fernando Soto
ID: 40444697
The dynamic type is causing the issue. try it like this.

dynamic outputs = (from output in wscgsContext.Searches
                   group output by new { Key = output.City } into cityGroup
                   select cityGroup.Key).Distinct().OrderBy(c => c);

foreach (var output in outputs)
{
    cmbCity.Items.Add(output.Key);
}

Open in new window

0
 
LVL 33

Author Comment

by:Mike Eghtebas
ID: 40444703
Hi Fernando,

Without OrderBy it works fine:
      dynamic outputs = (from output in wscgsContext.Searches
                           group output by new { Key = output.City } into cityGroup
                           select cityGroup.Key).Distinct();//.OrderBy(c => c);

Open in new window


But with Orderby, I get Cannot order by type '<>f__AnonymousType0`1[System.String]'. at foreach.
0
 
LVL 33

Author Comment

by:Mike Eghtebas
ID: 40444710
Valliappan AN,

I tried, this is what I got:errors
0
 
LVL 62

Expert Comment

by:Fernando Soto
ID: 40444716
Mike, please see my post [Here] I have modified it to work with dynamic type.

I used my original query but made a couple of changes to the for loop.
0
 
LVL 33

Author Comment

by:Mike Eghtebas
ID: 40444721
I had used:

dynamic outputs = (from output in wscgsContext.Searches
                   group output by new { Key = output.City } into cityGroup
                   select cityGroup.Key).Distinct().OrderBy(c => c);

foreach (var output in outputs)
{
    cmbCity.Items.Add(output.Key);
}

Open in new window


Exactly as you had. I am getting error with OrderBy included:  Cannot order by type '<>f__AnonymousType0`1[System.String]'. at foreach.
0
 
LVL 62

Assisted Solution

by:Fernando Soto
Fernando Soto earned 150 total points
ID: 40444732
Mike, can you place a breakpoint on the variable output in the foreach statement and when it causes an exception select the variable output and right click and select add to the Watch window. Then in the Watch window expand all nodes if any and take a screen shot and post here.

By the way I tested my solution using the dynamic type and it does work on my system.
0
 
LVL 9

Expert Comment

by:Valliappan AN
ID: 40444733
Can you check these please :

dynamic outputs = (from output in wscgsContext.Searches
                   select output.City)
                   .Distinct();

and then,

dynamic outputs = (from output in wscgsContext.Searches
                   select output.City)
                   .Distinct().OrderBy(c => c);

 hth.
0
 
LVL 33

Author Comment

by:Mike Eghtebas
ID: 40444767
Sorry for the delay, brb
0
 
LVL 33

Expert Comment

by:it_saige
ID: 40444770
Have you tried it this way?
dynamic outputs = (from output in wscgsContext.Searches
                   group output by new { Key = output.City } into cityGroup
                   orderby cityGroup.Key
                   select cityGroup.Key).Distinct();

foreach (var output in outputs)
{
    cmbCity.Items.Add(output.Key);
}

Open in new window


-saige-
0
 
LVL 62

Expert Comment

by:Fernando Soto
ID: 40444780
Hi -saige-, that is the same exact solution as I gave [here].
0
 
LVL 33

Author Comment

by:Mike Eghtebas
ID: 40444787
Fernando,
The screenshot is attached.  Please let me know what particular nodes you want to see.

Saige,
I used the code it is giving the exact error.

Valliappan AN,
I tired both. There is nor error but also there is no data the combo box.

FYI: My controls, despite their names are listboxes not combo boxes it it makes any difference. I will rename them later as lstCity, etc.
Watch-1.png
0
 
LVL 33

Accepted Solution

by:
it_saige earned 350 total points
ID: 40444801
Sorry Fernando, I did not see that...  Here is my example program using Fernando's recommendation.  I also removed the .Distinct() call because you are already returning distinct values by using the groupby method.  The real resolution was to have the enumerable ordered before you group it:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace EE_Q28562829
{
	class Customer
	{
		public string Name { get; set; }
		public string City { get; set; }
	}

	class Program
	{
		static void Main(string[] args)
		{
			var customers = new List<Customer>() 
			{ 
				new Customer() { City = "St. John", Name = "Carl" },
				new Customer() { City = "Petersburgh", Name = "Peter" },
				new Customer() { City = "Riderstown", Name = "John" },
				new Customer() { City = "Andrews", Name = "Thomas" },
				new Customer() { City = "Riderstown", Name = "Nancy" },
				new Customer() { City = "St. John", Name = "Mindy" },
				new Customer() { City = "Petersburgh", Name = "Daryl" },
				new Customer() { City = "Riderstown", Name = "Ringo" },
				new Customer() { City = "Charlestown", Name = "Mike" },
				new Customer() { City = "St. John", Name = "Nick" },
				new Customer() { City = "Petersburgh", Name = "Bob" },
				new Customer() { City = "Riderstown", Name = "Robert" },
				new Customer() { City = "Andrews", Name = "William" },
				new Customer() { City = "Riderstown", Name = "Billy" },
				new Customer() { City = "St. John", Name = "Denise" },
				new Customer() { City = "Petersburgh", Name = "Michelle" },
				new Customer() { City = "Riderstown", Name = "Terry" },
				new Customer() { City = "Charlestown", Name = "Doris" }
			};

			dynamic outputs = (from output in customers
						    orderby output.City
						    group output by new { Key = output.City } into cityGroup
						    select cityGroup.Key);

			foreach (var output in outputs)
				Console.WriteLine(output.Key);

			Console.ReadLine();
		}
	}
}

Open in new window


Produces the following output:Capture.JPG
-saige-
0
 
LVL 62

Expert Comment

by:Fernando Soto
ID: 40444802
Hi Mike, you used the wrong variable in the Watch window, I like to see output. Thanks.
0
 
LVL 62

Expert Comment

by:Fernando Soto
ID: 40444809
Mike do you really need to use a dynamic data type for the query seeming it is returning a collection of strings?
0
 
LVL 33

Author Comment

by:Mike Eghtebas
ID: 40444815
Fernando,

I had a vb.net code:
Dim states = From state In customerList Group state By state.State Into stateGroup = Group Select stateGroup.FirstOrDefault().State

Open in new window


I used http://converter.telerik.com/ to convert to c#. I do not know about the other options. Could you please help me with a text of a question I could post so I can get a bit understanding when and why we need to use dynamic as opposed to some other option?

Saige, Your last post works:
       dynamic outputs = (from output in wscgsContext.Searches
                           orderby output.City
                           group output by new { Key = output.City } into cityGroup
                           select cityGroup.Key);

        foreach (var output in outputs)
        {
            cmbCity.Items.Add(output.Key);
        }

Open in new window


Mike
0
 
LVL 33

Expert Comment

by:it_saige
ID: 40444818
Well he is asking because normally you would do this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace EE_Q28562829
{
	class Customer
	{
		public string Name { get; set; }
		public string City { get; set; }
	}

	class Program
	{
		static void Main(string[] args)
		{
			var customers = new List<Customer>() 
			{ 
				new Customer() { City = "St. John", Name = "Carl" },
				new Customer() { City = "Petersburgh", Name = "Peter" },
				new Customer() { City = "Riderstown", Name = "John" },
				new Customer() { City = "Andrews", Name = "Thomas" },
				new Customer() { City = "Riderstown", Name = "Nancy" },
				new Customer() { City = "St. John", Name = "Mindy" },
				new Customer() { City = "Petersburgh", Name = "Daryl" },
				new Customer() { City = "Riderstown", Name = "Ringo" },
				new Customer() { City = "Charlestown", Name = "Mike" },
				new Customer() { City = "St. John", Name = "Nick" },
				new Customer() { City = "Petersburgh", Name = "Bob" },
				new Customer() { City = "Riderstown", Name = "Robert" },
				new Customer() { City = "Andrews", Name = "William" },
				new Customer() { City = "Riderstown", Name = "Billy" },
				new Customer() { City = "St. John", Name = "Denise" },
				new Customer() { City = "Petersburgh", Name = "Michelle" },
				new Customer() { City = "Riderstown", Name = "Terry" },
				new Customer() { City = "Charlestown", Name = "Doris" }
			};

			var outputs = (from output in customers
						orderby output.City
						group output by output.City into cityGroup
						select cityGroup.FirstOrDefault().City);

			foreach (var output in outputs)
				Console.WriteLine(output);

			Console.ReadLine();
		}
	}
}

Open in new window


Produces the same output as above.

-saige-
0
DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

 
LVL 62

Expert Comment

by:Fernando Soto
ID: 40444821
Try reading this Microsoft documentation and see if it helps. If not let me know.

Using Type dynamic (C# Programming Guide)
0
 
LVL 33

Author Comment

by:Mike Eghtebas
ID: 40444823
For all that, I rely:

 WSCGSoftwareDataContext wscgsContext =  new WSCGSoftwareDataContext(cnn);
0
 
LVL 33

Author Comment

by:Mike Eghtebas
ID: 40444825
Fernando, I really value and appreciate inputs from you, Saige, and the other good experts at EE. Thank you for the link.

Mike
0
 
LVL 62

Expert Comment

by:Fernando Soto
ID: 40444826
Mike did the solution posted by Saige sort the list in the combo box?
0
 
LVL 33

Author Comment

by:Mike Eghtebas
ID: 40444832
Fernando, Yes, it did. I read the link. Could you possibly rewrite the following without use of dynamic?
dynamic outputs = (from output in wscgsContext.Searches
                           orderby output.City
                           group output by new { Key = output.City } into cityGroup
                           select cityGroup.Key);

        foreach (var output in outputs)
        {
            cmbCity.Items.Add(output.Key);
        }

Open in new window


Would it be like:

Search outputs = (from output in wscgsContext.Searches
0
 
LVL 62

Expert Comment

by:Fernando Soto
ID: 40444856
This should work.

String[] outputs = (from output in wscgsContext.Searches
                    orderby output.City
                    group output by new { Key = output.City } into cityGroup
                    select cityGroup.Key).ToArray();

cmbCity.Items.AddRange(output);

Open in new window

0
 
LVL 33

Expert Comment

by:it_saige
ID: 40444857
Mike, my follow-up post rewrites it without using dynamic.

-saige-
0
 
LVL 33

Expert Comment

by:it_saige
ID: 40444859
Nice use of .addrange fenando.  😃
0
 
LVL 33

Author Comment

by:Mike Eghtebas
ID: 40444886
Fernando, With this code there are 2 errors:

String[] outputs = (from output in wscgsContext.Searches
                    orderby output.City
                    group output by new { Key = output.City } into cityGroup
                    select cityGroup.Key);

        foreach (var output in outputs)
        {
            lstCity.Items.Add(output.Key);
        }

Two complains with String[]:
1. select : Cannot implicitly converr 'System.Ling.IQueryable<Annonymus.Type#>' to 'string[]'.
2. Key: 'string' does not contain a definition for Key (I suppose it needs an extention of some sort)

Saige,

var outputs = (from o...  works fine.

Mike
0
 
LVL 62

Expert Comment

by:Fernando Soto
ID: 40444901
That is NOT exactly what I posted. I modified the query in a couple of places and got rid of the foreach loop, please re-read the post.
0
 
LVL 33

Author Comment

by:Mike Eghtebas
ID: 40444911
With Aplogy.

I tested the following code. I have 2 problems in bolded areas:

        String[] outputs = (from output in wscgsContext.Searches
                            orderby output.City
                            group output by new { Key = output.City } into cityGroup
                            select cityGroup.Key).ToArray();

        lstCity.Items.AddRange(output);

ToArray(): Extension 'a[ ] IEnumerable<' a>.ToArray<'a>()
                             Anonymous Types:
                             'a is nw { string Key }
                             Creates an array from a System.Collections.Generic.IEnumerable<T>.
                              Coonot imlcitly convert type Anonymous#1[]' to 'string'.

output:  The name output doesn't exist in the current context.
0
 
LVL 33

Expert Comment

by:it_saige
ID: 40444913
You have to get rid of the anonymous type.  Remove the 'new { Key = output.City }'.  So it would look like:
string[] outputs = (from output in wscgsContext.Searches
		orderby output.City
		group output by output.City into cityGroup
		select cityGroup.FirstOrDefault().City).ToArray();

lstCity.Items.AddRange(outputs);

Open in new window


-saige-
0
 
LVL 33

Author Comment

by:Mike Eghtebas
ID: 40444936
Saige,
Please see the image for the error.error2
0
 
LVL 33

Expert Comment

by:it_saige
ID: 40444943
Well that is simple enough.  This should do the trick:
ListItem[] outputs = (from output in wscgsContext.Searches
		orderby output.City
		group output by output.City into cityGroup
		select new ListItem(cityGroup.FirstOrDefault().City)).ToArray();

lstCity.Items.AddRange(outputs);

Open in new window


-saige-
0
 
LVL 33

Author Comment

by:Mike Eghtebas
ID: 40444954
Saige,

If you get this working, do I owe you another 500 point LOL. All I had for this question are spent. See the result in the attached image. So far I do not owe any point but pretty soon it is going to happen:Error3
BTW, my control is list box not listview just in case.
0
 
LVL 33

Expert Comment

by:it_saige
ID: 40444960
Change it to ListItem in both places, I had misread the type in your post.  So it would be like:
ListItem[] outputs = (from output in wscgsContext.Searches
		orderby output.City
		group output by output.City into cityGroup
		select new ListItem(cityGroup.FirstOrDefault().City)).ToArray();

lstCity.Items.AddRange(outputs);

Open in new window


-saige-
0
 
LVL 33

Author Comment

by:Mike Eghtebas
ID: 40444967
It work. But how am I going pay you? Maybe wash your car?
0
 
LVL 33

Expert Comment

by:it_saige
ID: 40444970
LOL...  It's all good... :)

-saige-
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

This article is for Object-Oriented Programming (OOP) beginners. An Interface contains declarations of events, indexers, methods and/or properties. Any class which implements the Interface should provide the concrete implementation for each Inter…
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 tutorial gives a high-level tour of the interface of Marketo (a marketing automation tool to help businesses track and engage prospective customers and drive them to purchase). You will see the main areas including Marketing Activities, Design …
Hi friends,  in this video  I'll show you how new windows 10 user can learn the using of windows 10. Thank you.

863 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

Need Help in Real-Time?

Connect with top rated Experts

23 Experts available now in Live!

Get 1:1 Help Now