Solved

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

Posted on 2014-11-15
35
617 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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 63

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 34

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
Salesforce Has Never Been Easier

Improve and reinforce salesforce training & adoption using WalkMe's digital adoption platform. Start saving on costly employee training by creating fast intuitive Walk-Thrus for Salesforce. Claim your Free Account Now

 
LVL 34

Author Comment

by:Mike Eghtebas
ID: 40444710
Valliappan AN,

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

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 34

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 63

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 34

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 63

Expert Comment

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

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 63

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 63

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 34

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
 
LVL 63

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 34

Author Comment

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

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

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 63

Expert Comment

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

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 63

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 34

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 63

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 34

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 34

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 34

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 34

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

Space-Age Communications Transitions to DevOps

ViaSat, a global provider of satellite and wireless communications, securely connects businesses, governments, and organizations to the Internet. Learn how ViaSat’s Network Solutions Engineer, drove the transition from a traditional network support to a DevOps-centric model.

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…
This article shows how to deploy dynamic backgrounds to computers depending on the aspect ratio of display
Although Jacob Bernoulli (1654-1705) has been credited as the creator of "Binomial Distribution Table", Gottfried Leibniz (1646-1716) did his dissertation on the subject in 1666; Leibniz you may recall is the co-inventor of "Calculus" and beat Isaac…
Attackers love to prey on accounts that have privileges. Reducing privileged accounts and protecting privileged accounts therefore is paramount. Users, groups, and service accounts need to be protected to help protect the entire Active Directory …

726 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