Reputation: 5962
When using the following code (simplified), I get the error
"Unable to cast the type 'System.DateTime' to type 'System.Object'. LINQ to Entities only supports casting Entity Data Model primitive types."
in the line with the return statement:
public MyRepository<Post>
{
public Expression<Func<Post, object>> DefaultOrder;
public MyRepository()
{
DefaultOrder = p => p.PublishedOn;
}
public IQueryable<Post> All()
{
var entities = new MyDbContext().Set<Post>();
return entities.OrderByDescending(DefaultOrder);
}
}
I used the same code with db4o/db4o.Linq instead of Entity Framework and there was no problem.
So here my questions:
EDIT:
Found a solution, that works for me, replaced the default order expression with an order method:
public MyRepository<T>
{
public Func<IQueryable<T>, IOrderedQueryable<T>> DefaultOrderMethod;
public MyRepository()
{
DefaultOrderMethod = o => o.OrderBy(x => x.PublishedOn);
}
public IQueryable<T> All()
{
var entities = new MyDbContext().Set<T>();
return DefaultOrderMethod(entities);
}
}
Upvotes: 1
Views: 802
Reputation: 12854
The second type of the expression passed into the OrderBy extension method is inferred from the type that is returned by the expression. It's expecting a Expression>. So if you're going to store the sort expression you need to explicitly give it the TOrderBy type.
public MyRepository<Post>
{
public Expression<Func<Post, DateTime>> DefaultOrder;
public MyRepository()
{
DefaultOrder = p => p.PublishedOn;
}
public IQueryable<Post> All()
{
var entities = new MyDbContext().Set<Post>();
return entities.OrderByDescending(DefaultOrder);
}
}
.NET does not support boxing/unboxing a generic parameter type unless you're using .NET 4.0 and use interfaces via covariance and contravariance which would not work for your example.
Again this is just how the generic system works in .NET. The only reason something like this works...
Query.OrderBy(x => x.PublishedOn)
... is because the TOrderBy type can be inferred from the expression return type (DateTime).
Upvotes: 1