0

I have these LINQ queries :

        var type1 = (from ftr in db.TB_FTR
                              join mst in db.TB_MST on ftr.MST_ID equals mst.MST_ID
                              join trf in db.TYPE_ID on mst.TYPE_ID equals trf.ID
                              where ftr.CITY == city && ftr.COUNTY == county
                              select new MyType { City = ftr.CITY, County = ftr.COUNTY Type = trf.TYPE }
              ).OrderBy(i => i.City);

        var type2 = type1.GroupBy(i => new { i.City, i.County, i.Type })
            .Select(group => new { Name = group.Key, MyCount = group.Count() })
            .OrderBy(x => x.Name).ThenByDescending(x => x.MyCount)
            .GroupBy(g => new { g.Name.City, g.Name.County })
            .Select(g => g.Select(g2 =>
            new { Name = new  { g.Key.City, g.Key.County, g2.Name.Type }, g2.MyCount })).Take(1000).ToList();

As you see the 2nd query returns an anonymous type. But I want to use these queries in a method. So I can't return anonymous type. How can I make type2 as a non-anonymous type?

I have prepared two objects for that :

public class MyType
{
        public string City { get; set; }
        public string County { get; set; }
        public string Type { get; set; }
}

public class ProcessedType 
{
public MyType Name {get; set;}
public int MyCount {get; set;}
}

But I couldn't use them properly because I probably misplaced them in the query. Can you help me so that I can make the second query return a defined object? Thanks.

3 Answers 3

1

You have this in your code:

new { Name = new  { g.Key.City, g.Key.County, g2.Name.Type }, g2.MyCount }

Which are still anonymous types. You have to put the actual type names in there to be able to return them:

new ProcessedType { Name = new  MyType { g.Key.City, g.Key.County, g2.Name.Type }, g2.MyCount }

Looking at your code, you should also be able to assign the existing Name too:

new ProcessedType { Name = g2.Name, g2.MyCount }
Sign up to request clarification or add additional context in comments.

Comments

1

Whenever you write new not followed by a type-name you create an instance of an anoynmous type. As you correctly found out you can´t pass those instances to other methods (effectivly you can as even anonymous types inherit from System.Object, but this way you lose all the type-information of your actual type).

In your case you allready have a named type - ProcessedType. So instead of this:

new { Name = new  { g.Key.City, g.Key.County, g2.Name.Type }, g2.MyCount }

use this:

new ProcessedType
{ 
    Name = new  MyType { g.Key.City, g.Key.County, g2.Name.Type }, 
    MyCount = g2.MyCount
}

Why is this error? Well, how should the compiler know that you´re actually refering to ProcessedType instead of any other type that may have the same properties MyTypüe and MyCount? It´s impossible for the compiler to guess the type to be inferred here, in particular there´s no implicit conversion from an anonymous type to ProcessedType.

EDIT: the only assumption that coms to my mind refering my first section is an implicitely typed array, where you can also write new[] { 1 } which will implicitely be declared as int[].

Comments

1

Try this

var type2 = type1.GroupBy(i => new { i.City, i.County, i.Type })
        .Select(group => new { Name = group.Key, MyCount = group.Count() })
        .OrderBy(x => x.Name).ThenByDescending(x => x.MyCount)
        .GroupBy(g => new { g.Name.City, g.Name.County })
        .Select(g => g.Select(g2 =>
        new ProcessedType{ Name = new MyType { City = g.Key.City, County = g.Key.County, Type = g2.Name.Type }, MyCount = g2.MyCount })).Take(1000).ToList();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.