3

I'm trying to cast an IEnumerable of an inherited type to IEnumerable of base class.

Have tried following:

var test = resultFromDb.Cast<BookedResource>();

return test.ToList();

But getting error:

You cannot convert these types. Linq to Entities only supports conversion primitive EDM-types.

The classes involved look like this:

public partial class HistoryBookedResource : BookedResource
{
}

public partial class HistoryBookedResource
{
    public int ResourceId { get; set; }
    public string DateFrom { get; set; }
    public string TimeFrom { get; set; }
    public string TimeTo { get; set; }
}

public partial class BookedResource
{
    public int ResourceId { get; set; }
    public string DateFrom { get; set; }
    public string TimeFrom { get; set; }
    public string TimeTo { get; set; }
}

[MetadataType(typeof(BookedResourceMetaData))]
public partial class BookedResource
{
}

public class BookedResourceMetaData
{
    [Required(ErrorMessage = "Resource id is Required")]
    [Range(0, int.MaxValue, ErrorMessage = "Resource id is must be an number")]
    public object ResourceId { get; set; }

    [Required(ErrorMessage = "Date is Required")]
    public object DateFrom { get; set; }

    [Required(ErrorMessage = "Time From is Required")]
    public object TimeFrom { get; set; }

    [Required(ErrorMessage = "Time to is Required")]
    public object TimeTo { get; set; }
}

The problem I'm trying to solve is to get records from table HistoryBookedResource and have the result in an IEnumerable<BookedResource> using Entity Framework and LINQ.

UPDATE:

When using the following the cast seams to work but when trying to loop with a foreach the data is lost.

resultFromDb.ToList() as IEnumerable<BookedResource>;

UPDATE 2:

Im using entity frameworks generated model, model (edmx) is created from database, edmx include classes that reprecent the database tables.

In database i have a history table for old BookedResource and it can happen that the user want to look at these and to get the old data from the database entity framework uses classes with the same name as the tables to receive data from db. So i receive the data from table HistoryBookedResource in HistoryBookedResource class.

Because entity framework generate the partial classes with the properties i dont know if i can make them virtual and override.

Any suggestions will be greatly appreciated.

tereško
  • 58,060
  • 25
  • 98
  • 150
MikeAlike234
  • 759
  • 2
  • 12
  • 29
  • 1
    What is the point having two exactly the same classes `BookedResource` and `HistoryBookedResource`? – VladL Nov 01 '13 at 20:22
  • You are shadowing the resources, so after you perform the cast you can't read the data anymore. (Also you are not going from `IEnumerable` To `IEnumerable` you are going from `IQueryable` To `IQueryable`) – Scott Chamberlain Nov 01 '13 at 20:29
  • Thats right the data disappears, but first when I use it in a foreach. Could you please elaborate a what you mean by "shadowing", and why its IQueryable and not IEnumerable? – MikeAlike234 Nov 01 '13 at 21:06
  • You declare the same property in the parent as the child without using the keyword `override`, that causes [shadowing](http://stackoverflow.com/questions/673779/what-is-shadowing). To fix that each property must be marked `virtual` in the parent and each property in the child must be marked with `override`. Also looking at the error you got I am willing to bet that `resultFromDb` is a `IQueryable`, that's what I meant. Can you explain why you have the same properties in `BookedResource` and `HistoryBookedResource`? is `HistoryBookedResource` supposed to be some kind of DTO? – Scott Chamberlain Nov 01 '13 at 21:24
  • Look at update, to long for comment – MikeAlike234 Nov 01 '13 at 21:50

2 Answers2

6

Typically you use AsEnumerable<T> in such cases:

var test = resultFromDb.AsEnumerable().Cast<BookedResource>();

This has the advantage of not enumerating the whole result at once (you don't loose the laziness).

BartoszKP
  • 34,786
  • 15
  • 102
  • 130
4

try with:

resultFromDb.AsEnumerable().Cast<BookedResource>();
Sebastian Piu
  • 7,838
  • 1
  • 32
  • 50