1

When using TPH I have different types inheriting from a base. We have a search that queries across the abstract type. In the results, we want to show the type:

ie. abstract Vehicle

Car: Vehicle Truck: Vehicle

in the results, I want to show 'type' - ie. 'Car' and 'Truck'.

I attempted to use GetType().Name but this fails.

Here is sample:

 IQueryable<CompanySearchResult> q = from company in _ctx.Companies
                                                select new CompanySearchResult
                                                {                                                        
                                                    CompanyName = company.CompanyName,
                                                    CompanyId = company.Id,
                                                    Type = company.GetType().Name
                                                };
Yuliam Chandra
  • 14,494
  • 12
  • 52
  • 67
Steve
  • 387
  • 4
  • 11
  • 1
    It shouldn't fail and it is a right approach. – Wiktor Zychla Sep 26 '14 at 17:36
  • This is the error I get: System.NotSupportedException: LINQ to Entities does not recognize the method 'System.Type GetType()' method, and this method cannot be translated into a store expression. – Steve Sep 26 '14 at 17:51

1 Answers1

1

You have to postpone projection until you have entities in memory

 IEnumerable<CompanySearchResult> q = 
    _ctx.Companies.ToList()
        .Select( company =>
            new CompanySearchResult
            {                                                        
                CompanyName = company.CompanyName,
                CompanyId = company.Id,
                Type = company.GetType().Name
            } );

In particular, this means that you shouldn't still have IQueryable after the projection, as you operate on an in-memory collection.

Wiktor Zychla
  • 47,367
  • 6
  • 74
  • 106
  • I'm having a secondary issue now where I'm implementing sorting and paging on this query and I'm unable to sort by the discriminator when I issue the query – Steve Sep 27 '14 at 18:05
  • ie. 'companySearch.sortBy = companySearch.sortBy ?? "CompanyName"; query = query.OrderBy(companySearch.sortBy + (companySearch.sortDesc ? " descending" : "")) .Skip((companySearch.page - 1) * companySearch.pageSize) .Take(companySearch.pageSize); – Steve Sep 27 '14 at 18:06
  • Just want to say, it seems short sided that they didn't allow for mapping to this discriminator field, even if it was 'readonly' (although it's another short coming that you can't change types)... all this work around for what is a rather simple concept ? – Steve Sep 27 '14 at 18:09
  • ok, I found an answer to this here: http://blog.brentmckendrick.com/group-or-order-by-sub-type-using-linq-to-entities/ – Steve Sep 27 '14 at 18:23
  • For those that want to know the approach to this (which is unfortunate again that MS didn't think this through) is that for my abstract type, I create a 'Type' string property (could be an enum), then each subtype, set it on ctor. Then I use this property to query against, saving the headache of not having this available. It creates 'yet another' column to specify this value. – Steve Sep 27 '14 at 20:32