【发布时间】:2017-07-24 09:47:05
【问题描述】:
我想编写一个被子类覆盖的抽象方法,该方法的作用是返回一个表达式,以便随后在 LINQ OrderBy() 中使用。像这样的:
注意:Message 继承自 Notes 类,MyModel 继承自 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;
}
}
现在如果我尝试通过这种方式订购:
var orderedQuery = myQueryable.OrderBy(OrderByField());
我收到此错误:
'无法将类型“System.Int32”转换为类型“System.Object”。 LINQ to Entities 仅支持转换 EDM 基元或枚举类型。'
我可以马上说类型参数对象是问题的原因。因此,当我将类型参数更改为 int 时,只要我按 int 字段(例如字段item_no)排序,它就可以正常工作。
第一季度。我怎样才能让它工作?当然,我可以使用字符串属性OrderByField 而不是那个表达式返回方法并按它排序,可能是通过为 IQueryable 编写一些扩展方法(可能使用this great answer)。但是我想在设置顺序时有更多的智能感知。
第二季度。如何从OrderByField() 方法返回的表达式中按列获取订单名称。显然,我尝试过的方法不起作用。 member 总是为空。
编辑:我对方法的类型参数做了一些更改。很抱歉没有第一次这样做。
【问题讨论】:
-
你能不能将
Notes设为从该表达式返回的数据类型通用? -
@Damien 我不确定我是否理解你的意思:-(你能说得更具体一点吗?
-
如果您的意思是
Expression<Func<MsgModel, T>> OrderByField<T>(),那么我会收到此错误:无法将 lambda 表达式转换为预期的委托类型,因为块中的某些返回类型不能隐式转换为委托返回类型 -
嗯,你可以这样定义它(
Expression<Func<Notes, object>>),但你不能直接在OrderBy中使用它。如果您需要OrderBy的智能感知,那么为什么不使用OrderBy本身呢? -
我的意思是,它不应该被建模为抽象的
Expression<Func<...>>,而是抽象的Order方法,例如public abstract IOrderedQueryable<MsgModel> Order(IQueryable<MsgModel> source);和return source.OrderBy(m => m.item_no);这样的实现
标签: c# linq lambda expression-trees