Entity Framework 4.1: Repository with "DefaultOrder Property"
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<P开发者_Python百科ost> 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:
- Why is this error happening?
- Is there an alternative solution, which lets me define my DefaultOrder in the same (a similar) manner as I do now?
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);
}
}
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).
精彩评论