Different Implementation of Cast in Linq To SQL And Entity Framework

To set the stage of what I am going to blog about, I would recommend that you read by earlier blog posting here where I have talked about how the cast operator works. In short when you use cast operator with Linq to SQL to fetch a particular concrete type, you end up making a call to the database that fetches all records and than cast is performed in memory to cast the objects to the type passed in as a generic type. If the object cannot be cast to the correct type, the object is assigned a null value. The implementation is very similar to as operator in C# where if the object cannot be cast to right type, the reference of the object is set to null. Important point to understand is, even though your Linq query may not give the results you desire, but the query wont crash. However if you were to write the same query in Linq to entities or entity framework, you get a runtime exception stating that a cast is not valid. Below is an example that shows the behavior?

image

Running the above code with entity framework throws an exception.

Unable to cast the type Employee to type HourlyEmployee. LINQ to Entities only supports casting Entity

When I run the same piece of the code in Linq to SQL, I don't get exception but I do get  2 items in my collection, 1 being Hourly Employee and second is null because that employee is a Salaried Worker.

image

I am not sure which implementation is correct but I do think that which ever implementation is correct should be correct in both providers so that at the very least when we are migrating code from Linq to SQL to entity framework, implementation does not change and cause weird errors at runtime. 

2 Comments

  • The EF implementation seems right to me - it matches the behaviour of the Cast method with Linq to Objects.

    If you only want to return the items which can successfully be cast to a type, use the OfType method instead. Hopefully, the SQL and EF versions should be able to convert that to a database query which only returns the required records.

  • This seems correct at first but fails when you try to cast to an interface/base type that the object implements or an object it inherits.

    This seems counter intuative and makes working with collections difficult unless you know what their type will be before hand.

    Steve Naughton.

Comments have been disabled for this content.