jason
jason

Reputation: 7164

How to use objects instead of anonymous Types

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.

Upvotes: 0

Views: 175

Answers (3)

barzozwierz
barzozwierz

Reputation: 148

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();

Upvotes: 1

MakePeaceGreatAgain
MakePeaceGreatAgain

Reputation: 37000

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[].

Upvotes: 1

Patrick Hofman
Patrick Hofman

Reputation: 156918

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 }

Upvotes: 1

Related Questions