I want to write an abstract method to be overridden by child classes, and what the method does is return an expression to be subsequently used in LINQ OrderBy()
. Something like this:
Note: Message
inherits from Notes
class, and MyModel
inherits from MsgModel
.
public class Notes
{
// abstract definition; using object so that I can (I hope) order by int, string, etc.
public abstract Expression<Func<MsgModel, object>> OrderByField();
// ...
private string GetOrderByFieldName()
{
// I am not sure how to write this
// This is my problem 2. Please see below for problem 1 :-(
var lambda = OrderByField() as LambdaExpression;
MemberExpression member = lambda.Body as MemberExpression;
PropertyInfo propInfo = member.Member as PropertyInfo;
return propInfo.Name;
}
}
public class Message : Notes
{
// second type parameter is object because I don't know the type
// of the orderby field beforehand
public override Expression<Func<MyModel, object>> OrderByField()
{
return m => m.item_no;
}
}
Now if I try to order by this way:
var orderedQuery = myQueryable.OrderBy(OrderByField());
I get this error:
'Unable to cast the type 'System.Int32' to type 'System.Object'. LINQ to Entities only supports casting EDM primitive or enumeration types.'
I can rightaway say that type parameter object is the cause of the problem. So, when I change the type parameter to int, it works fine as long as I am ordering by an int field (e.g. the field item_no
).
Q1. How can I get this to work? Surely, I can use a string property OrderByField
instead of that expression-returning method and order by it, probably by writing some extension method for IQueryable (maybe using this great answer). But I want to have more intellisense while setting the order by.
Q2. How can I get the name of the order by column from the expression returned by the method OrderByField()
. Obviously what I have tried with doesn't work. The member
always gets null.
Edit: I have made some changes to the type parameters of the methods. Sorry for not doing it the first time.