Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Help me understand "LINQ to Entities only supports casting Entity Data Model primitive types"

I have a unit of work and a repository using EF 4 and POCOs. Since EF requires an ordered set before it can Skip() and Take(), I added the following unit test (without mocks) just to pull out a record to see if it worked.

var myList = UOW.EntityRepo.Get( orderbyLambda: p => p.ID, page: 1, pageSize: 1);

This results in an expression of orderbyLambda = {p => Convert(p.ID)} and an error during enumeration. The ID is a tinyint (Int16 / short)

So why does this fail to order by the ID? More about the error

Unable to cast the type 'System.Int16' to type 'System.Object'.

I define the orderbyLambda as Expression<Func<E, object>> orderbyLambda

EDIT:

The real killer is if I do this:

 orderbyLambda:  p => new { p.ID }

It works... Why?

like image 446
Zachary Scott Avatar asked Feb 10 '11 06:02

Zachary Scott


1 Answers

It is spotting "order by {object}" and panicking; it knows how to order by string, int, short, DateTime, etc - but object is a bit too vague.

You're going to need the actual lambda to be typed correctly; the simplest approach would be to make Get generic, i.e.

.... Get<TIdentity>(
         Expression<Func<E, TIdentity>> orderbyLambda, int page, int pageSize)

and then:

orderbyLambda: p => p.ID

should (without you changing the code at the caller) automatically make that a Get<short>(...) in this case via generic type inference. The other option is to leave it as <E,object>, but re-write the expression tree at the receiver. More work.

like image 95
Marc Gravell Avatar answered Oct 12 '22 22:10

Marc Gravell